目录
创建文件(夹),删除文件,移动(重命名)文件,打印分隔符
//1参构造方法
// File haha = new File("D://1.txt");
// boolean flag = haha.createNewFile(); //创建文件
// System.out.println(flag?"创建成功":"创建失败");
//通过创建文件夹创建文件
File dir = new File("D://haha");
//dir.mkdirs();//创建文件夹
//2.两参构造方法
File a = new File(dir,"a.txt");
a.createNewFile();
File b = new File(dir,"b.txt");
b.createNewFile(); //创建文件
//文件删除
a.delete();
b.delete();
//移动(重命名)文件
File file = new File("D://la.zip");
File newfile = new File("E://垃圾.zip");
file.renameTo(newfile);
//打印当前操作系统的分隔符
System.out.println(File.pathSeparator); //路径分隔符
System.out.println(File.separator);//名称分隔符
文件遍历
public static void main(String[] args) {
File e = new File("D:\\");
File[] files = e.listFiles();
listFile(files);
}
public static void listFile(File[] files) {
if (files != null && files.length > 0) {
for (File file : files) {
if (file.isFile()) {//找到文件
if (file.getName().endsWith(".avi")) { //找到一个.avi为后缀的文件
if (file.length() > 10 * 1024 * 1024) { //打印大于10MB的文件
System.out.println("找到了一个avi文件:" + file.getAbsolutePath());
}
}
}
else {//找到文件夹
File[] files2 = file.listFiles(); // 再取文件夹里的所有子文件
listFile(files2); //递归遍历,判断是文件还是文件夹。
}
}
}
}
文件过滤
public static void main(String[] args) {
File e = new File("e:\\");
listFiles(e);
}
public static void listFiles(File file){
//1.创建一个过滤器,并描述规则
FileFilter filter = new AVIFileFilter();
// 2.通过文件获取子文件夹
File[] files = file.listFiles(filter); //listFiles:获取文件列表
if (files!=null&&files.length>0) {
for (File f : files) {
if (f.isDirectory()) {
listFiles(f); //继续处理文件夹
} else {
System.out.println("发现一个avi:" + f.getAbsolutePath());
}
}
}
}
/**
* 文件过滤器
*/
static class AVIFileFilter implements FileFilter {
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".avi")||pathname.isDirectory()){
return true; //表示保留
}
return false; //表示不保留
}
}
相对路径和绝对路径
-
绝对路径:从盘符开始,是一个完整的路径,例如:c://a.txt
-
相对路径:在java代码中是相对于项目目录路径,这是一个不完整的便捷路径,在java开发中很常用.例如:a.txt
IO流概述
-
可以将这种数据传输操作(从C盘拷贝文件到D盘),看做一种数据的流动,按照流动的方向分为输入Input和输出Output。
-
Java中的IO操作主要指的是java.io包下的一些常用类的使用
-
IO流的分类:
-
按照流的方向来分:可以分为输入流和输出流
-
按照流动的数据类型来分,可以分为:字节流和字符流
-
字节流
-
输入流:顶级父类InputStream
-
输出流:顶级父类OutputStream
-
-
字符流
-
输入流:顶级父类Reader
-
输出流:顶级父类Writer
-
-
-
-
一切皆字节:
-
计算机中的任何数据(文本,图片,视频,音乐等等)都是以二进制的形式存储的。
-
在数据传输时,也都是二进制的形式存储的。
-
后续学习的任何流,在传输时底层都是二进制。
-
OputStream的方法
FileOputStream的方法
FileInputStream的方法
构造方法
常用方法
原因:实际上这个byte数组,都是同一个数组,而新写的内容是覆盖原来内容的位置
read()方法
//InputStream
FileInputStream fis = new FileInputStream("D://1.txt"); //创建流
/*
//这种方法不常用
while (true){
byte b = (byte)fis.read(); //read():从输入流中读取一个字节的数据。
if (b==-1){
break;
}*/
//这种一次读取一组内容的方式更为常用,基本不用每次读取一个字节的方式
//文件写入的内容为26个英文字母
byte[] bytes = new byte[10];
int len =fis.read(bytes);//10 //read(数组b)从:此输入流 b.length最多 b.length字节的数据读 b.length字节数组。
System.out.println(new String(bytes,0,len));//把数组bytes转为字符串,从0开始读取,读取len个长度的内容
len = fis.read(bytes);//10
System.out.println(new String(bytes,0,len));
len = fis.read(bytes);//6
System.out.println(new String(bytes,0,len));
len = fis.read(bytes);//没有内容了,读取的长度应为-1
System.out.println(len);
fis.close();
}
机械硬盘的优点:能够长时间(几十年)存储,长时间掉电也不会丢失数据。耐高低温。通过指针来读写数据,指针转动速度越快,声音越大。
固态硬盘: 读写快,但不耐高温。高温或者长时间储存,数据会丢失。
字节流读取文字
//InputStream
FileInputStream fis = new FileInputStream("b.txt"); //创建流
/*while (true){
byte b = (byte)fis.read(); //read():从输入流中读取一个字节的数据。
if (b==-1){
break;
}*/
//这种一次读取一组内容的方式更为常用,基本不用每次读取一个字节的方式
//文件写入的内容为26个英文字母
byte[] bytes = new byte[10];
int len =fis.read(bytes);//10 //read(数组b)从:此输入流 b.length最多 b.length字节的数据读 b.length字节数组。
System.out.println(new String(bytes,0,len));//把数组bytes转为字符串,从0开始读取,读取len个长度的内容
len = fis.read(bytes);//10
System.out.println(new String(bytes,0,len));
len = fis.read(bytes);//6
System.out.println(new String(bytes,0,len));
fis.close();
字符输出
Filewriter的构造方法
常用方法
//writer
FileWriter fw = new FileWriter("D://b.txt",true);//true表示追加模式
//fw.write("锄禾日当午");
/*FileWriter fw2 = (FileWriter) fw.append("锄禾日当午");//append方法会返回一个调用对象
System.out.println(fw==fw2); //结果为True*/
//因此,我们可以连用append()方法
fw.append("锄禾日当午").append(",").append("谁知盘中餐");
fr.frush()//字符首先是存在缓存中,只有调用frush时才会将缓存中的字符输出到文件中。
fr.close();//每次调用close的时候,系统都会调用frush进行刷新。
字符读取
FileReader的构造方法
常用方法
FileReader fr = new FileReader("b.txt");
/* while (true){
int c = fr.read();//每次读取一个字符
if (c==-1){
break;
}
System.out.println((char)c);
}*/
char[] chars = new char[100];
int len = fr.read(chars); //数组默认值为0,这样的操作能够保证打印字符的长度,而不把数组中剩余的0打印出来。
System.out.println(new String(chars,0,len));
fr.close();
操作字符输出流时记得使用flush
-
flush的作用:字符首先是存在缓存中,只有调用frush时才会将缓存中的字符输出到文件中。每次调用close的时候,系统都会调用frush进行刷新。
Print与BufferReader
//字符输出(打印流)
PrintStream ps = new PrintStream("D://c.txt");
/*ps.println("锄禾日当午,汗滴禾下土");
ps.println("锄禾日当午,汗滴禾下土");
ps.println("锄禾日当午,汗滴禾下土");*/
/*PrintWriter pw = new PrintWriter("D://c.txt");//这是字符打印,在写入后需要使用flush来刷新缓存
pw.println("谁知盘中餐,粒粒皆辛苦");
pw.println("谁知盘中餐,粒粒皆辛苦");
pw.println("谁知盘中餐,粒粒皆辛苦");
pw.flush();*/
FileOutputStream fos = new FileOutputStream("D://c.txt");//字节流
PrintWriter pw = new PrintWriter(fos);//可以通过打印流将字节流转换为字符流
pw.println("锄禾日当午,汗滴禾下土哈哈哈");
pw.flush();
//缓存读取流,将字符输入流 转换为带有缓存 可以一次读取一行的缓存字符读取流
FileReader fw = new FileReader("D://c.txt"); //字符流
BufferedReader br = new BufferedReader(fw);
String text = br.readLine();//readline():每次可以读取一行,读到一行的末尾时会返回null
System.out.println(text);
收集异常日志
try {
String s = null;
s.toString();
}
catch (Exception e){
PrintWriter pw = new PrintWriter("D://bug.txt");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //格式化时间模版
pw.println(sdf.format(new Date())); //打印出错时间
e.printStackTrace(pw);//输出到文本中
pw.close();
}
Properties的储存和读取
//.properties文件与Properties类
/**
* 储存
*//*
Properties ppt = new Properties();// Properties类是一个hashtable类型,采用键值对的形式进行储存
ppt.put("name","金苹果");
ppt.put("图书简介","讲述了苹果种植的过程");
FileWriter fw = new FileWriter("D://book.properties");//必须以.properties为后缀名
ppt.store(fw,"存储了图书");//comments:对文件的注释
fw.close();*/
/**
* 读取
*/
Properties ppt = new Properties();//创建存储对象
Reader r = new FileReader("D://book.properties");
ppt.load(r);
//采用map中的get方法来打印键值对
//或者采用properties的getProperties()方法来打印键值对
System.out.println(ppt.getProperty("name"));
System.out.println(ppt.get("图书简介"));
}
序列化与反序列化
序列化:将对象在内存中存储的字节序列,存储在文件的方式来实现存储对象。
反序列化:从文件中读取对象。
-
要序列化的类,必须implements 接口Serializable,否则会报错
-
Serializable接口没有任何内容,这种接口称其为标记接口。
-
其属性的类也必须implements Serializable,否则会报错。
try-with-source
//try-with-resources
/* //1.7之前
*//**
* try的()的方法必须能调用close方法,当程序调用完try或catch里面的语句后,就会自动调用close方法来关闭流
*//*
try(FileReader fr = new FileReader("D://1.txt");) {
int c = fr.read();
System.out.println((char)c);
} catch (IOException e) {
e.printStackTrace();
}*/
/*//JDK9进行了优化
FileReader fr = new FileReader("D://1.txt");
PrintWriter pw = new PrintWriter("D://1.txt");
try(fr;pw) { //同1.7的要求和功能一样,不过这里允许传递对象
int c = fr.read();
System.out.println((char)c);
} catch (IOException e) {
e.printStackTrace();
}*/
ClossDemo d = new ClossDemo();
try(d){
}catch (Exception e){
}
}
static class ClossDemo implements Closeable{
@Override
public void close() throws IOException {
System.out.println("close方法被调用了");
}
}