温故而知新,今天重新梳理了一下IO流,
IO流有很多种,按照操作类型的不同分为两种:字节流和字符流。
按照输出反向的不同分为:输入流和输出流。
1、先说说 字节流
两个顶级父类(抽象类):InputStream / OutputStream
然后有很多子类可以实现,我们只说一个最常用的 FileInputStream / FileOutputStream
先看两个例子
//创建一个文件字节输入流
FileInputStream fis = new FileInputStream("C:\\Users\\Desktop\\io\\a.txt");
int b = 0;
while(true){
b = fis.read();
if(b == -1){ //当读取到字节为-1时,跳出循环
break;
}
System.out.println(b);
}
fis.close();
//创建一个字节输出流(加入 true后,就不会把之前文件中的内容清空,而是在后边追加)
FileOutputStream fos = new FileOutputStream("C:\\Users\\Desktop\\io\\b.txt",true);
String str = ",班门弄斧";
byte [] b = str.getBytes();//将字符串转换成字节
for(int i=0;i<b.length;i++){
fos.write(b[i]);
}
fos.close();
System.out.println("输出完毕!");
从中可以看到,其实输出和输入也就是调用read()、write()这两个方法即可。当然第一个例子输入流输出的只是文件中数据对应的字节而已,第二个例子是先把汉字转换成了字节,然后将字节写入了你要放的文件中。
1.1、再看下文件的拷贝
也就是复制文件,也很简单,就是先读一个文件,然后写入另一个文件即可。
//文件的拷贝
FileInputStream fis = new FileInputStream("C:\\Users\\Desktop\\简历.docx");
FileOutputStream fos = new FileOutputStream("C:\\Users\\Desktop\\io\\c.docx");
int b = 0;
long beginTime = System.currentTimeMillis();
while((b = fis.read()) != -1){
fos.write(b);
}
long endTime = System.currentTimeMillis();
System.out.println("复制文件所消耗的时间:"+(endTime- beginTime)+"ms"); //5568ms
fis.close();
fos.close();
然后就是通过字节流的方式复制文件太慢了,他是读到一个字节就去另外一个文件写入一个,频繁的读写,效率特别低。
举个例子:你有一批烤鸭需要从北京运往上海,如果你先取一只鸭子然后送到上海,再回来再取一只再去上海…是不是特别慢,得累死。
所以就把这批鸭子放到一辆卡车里,然后一块送到上海,那这样岂不是就运一次就可以了。那这个卡车就相当于是一个缓冲区,先把读到的数据放到缓存区中,然后一次性写入文件,岂不是快多了,对吧。
看下边的例子
//文件的拷贝
FileInputStream fis = new FileInputStream("C:\\Users\\Desktop\\简历.docx");
FileOutputStream fos = new FileOutputStream("C:\\Users\\Desktop\\io\\c.docx");
long beginTime = System.currentTimeMillis();
int b = 0;
//创建一个缓冲区用来读写文件
byte [] bt = new byte[1024];
while((b = fis.read(bt)) != -1){// 判断是否读到文件结尾
fos.write(bt, 0, b);//从第一个字节开始,向文件中写入b个长度的字节
}
long endTime = System.currentTimeMillis();
System.out.println("复制文件所消耗的时间:"+(endTime- beginTime)+"ms"); //10ms
fis.close();
fos.close();
IO包中还提供了两个带缓冲的字节流,BufferedInputStream 、BufferedOutputStream 这两个流内部都定义了一个大小为8192的字节数组,当调用read() write()方法的时候,首先会将读写到的数据存入定义好的字节数组中,然后一次性写入到文件中,类似上边的运烤鸭描述的那个例子。
//字节缓冲流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\Desktop\\简历.docx"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\Desktop\\io\\d.docx"));
int b = 0;
long beginTime = System.currentTimeMillis();
while((b=bis.read()) != -1){
bos.write(b);
}
long endTime = System.currentTimeMillis();
System.out.println("耗时:"+(endTime - beginTime)+"ms");
bis.close();
bos.close();
2、再说说 字符流
两个顶级父类(抽象类):Reader / Writer
常用的FileReader和FileWriter用于读写文件,BufferReader和BufferWriter是具有缓冲功能的流,他们可以提高效率。
//文件输入流
FileReader fr = new FileReader("C:\\Users\\Desktop\\io\\a.txt");
int c = 0;
while((c = fr.read()) != -1){
System.out.print((char)c);
}
fr.close();
//文件输出流
FileWriter fw = new FileWriter("C:\\Users\\Desktop\\io\\b.txt");
String str = "sdf水电费";
fw.write(str);
fw.write("\r\n");//换行
fw.write(str);
fw.close();
System.out.println("输出完毕!");
//缓冲流
BufferedReader br = new BufferedReader(new FileReader("C:\\Users\\Desktop\\io\\a.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\Desktop\\io\\b.txt"));
String str;
while((str = br.readLine())!= null){//一行一行的读
bw.write(str);
bw.newLine(); //换行
}
br.close();
bw.close();
System.out.println("输出完毕!");
3、还有一个最重要的File类
它提供了很多重要的方法,也比较基础。
getName()
exists()
createNewFile()
getPath()
getAbsolutePath() //绝对路径
getParent()
canRead() //判断File对象对应的文件或目录是否可读
canWrite() //判断File对象对应的文件或目录是否可写
isFile()
isDirectory()
listFiles() //返回File对象所有子文件和子目录的File数组
.
.
.
//遍历删除执行目录下的所有文件
public static void main(String[] args) throws IOException {
File f = new File("C:\\Users\\Desktop\\io");
deleteDir(f);
}
public static void deleteDir(File f){
if(f.exists()){//判断文件是否存在
File [] file = f.listFiles();//文件列表
for(File ff : file){
if(ff.isDirectory()){//如果是目录,
deleteDir(ff);//递归调用deleteDir方法
}else{
ff.delete();//删除文件
}
}
f.delete();//删除一个目录里面的文件后就删除这个目录
}
}
这只是最简单的几个IO流,其实还有很多流,以后再补充吧。