缓冲流(一)
缓冲流
使用缓冲流的目的就是提高读写效率。
缓冲流分为字节缓冲流和字符缓冲流
字节缓冲流为:
BufferedInputStream--字节输入缓冲流
BufferedOutputStream--字节输出缓冲流
字符缓冲流为:
BufferedReader--字符输入缓冲流
BufferedWriter--字符输出缓冲流
1.BufferedOutputStream--字节输出缓冲流
BufferedOutputStream类实现缓冲的输出,通过设置这种输出流,应用程序就可以将各个字节
写入底层输出流中,而不必每一个字节写入调用底层系统。
2.BufferedInputStream--字节输入缓冲流
BufferedInputStream为别的输入流添加缓冲功能,在创建BufferedInputStream时会创建一个内部缓冲数组,要回用于缓冲数据,提供性能。
二.字符缓冲流
1.BufferedWriter--字符输出缓冲流
将文本写入字符输出流,缓冲各个字符,从而提供高效的写入。可以指定缓冲区的大小,一般情况下,
默认的缓冲区大小就足够了。
2.BufferedReader--字符输入缓冲流
从字符输入流中读取信息,缓冲各个字符,从而实现高效读取。可以指定缓冲区的大小,一般情况下,缓冲区的大小就足够了。默认为8k。
先说字符缓冲流:
BufferedReader和BufferWriter类创建的对象称为缓冲输入、输出流,二者增强了读写文件的能力。
Java提供了更高级的流:BufferedReader流和BufferedWriter流,二者的源和目的地必须是字符输入流和字符输出流。缓冲流比字符流具有更强的读写能力。
BufferedReader类和BufferedWriter的构造方法分别是:
BufferedReader(Reader in);
BufferedWriter(Writer out);
BufferedReader流能够读取文本行,方法是readLine()。
BufferedReader类的方法write(String s, int off, int len)把字符串s写到指定的源中,参数off是s开始处的偏移量,len是写入的字符数量。
BufferedReader流有一个独特的向文件写入一个换行符的方法
newLine();
可以把BufferedReader和BufferedWriter称为上层流,把它们指向的字符流称为底层流。Java采用缓存技术将上层流和底层流连接。底层字符输入流首先将数据读入缓存,BufferedReader流再从缓存读取数据;BufferWriter流将数据写入缓存,底层字符输出流会不断地将缓存中的数据写入到目的地。当BufferedWriter流调用flush()刷新缓存或调用close()方法关闭时,即使缓存没有溢出,底层流也会立刻将缓存的内容写入目的地。
关闭输出流时要首先关闭缓存输出流,然后关闭缓冲输出流指向的流,即先关闭上层流再关闭底层流。在编写代码时只需关闭上层流,那么上层流将自动关闭。
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.io.Writer; public class Test09 { public static void main(String[] args) { // TODO Auto-generated method stub File fRead = new File("E:/test/test01.txt"); File fWrite = new File("E:/test/test02.txt"); try{ Writer out = new FileWriter(fWrite); BufferedWriter bufferWriter = new BufferedWriter(out); Reader in = new FileReader(fRead); BufferedReader bufferReader = new BufferedReader(in); String str = null; while((str = bufferReader.readLine()) != null) { bufferWriter.write(str); bufferWriter.newLine();//写入换行符 } bufferWriter.close(); out.close(); in = new FileReader(fWrite); bufferReader = new BufferedReader(in); while((str = bufferReader.readLine()) != null) { System.out.println(str); } bufferReader.close(); in.close(); } catch(IOException e) { } } }
但是字符缓冲流值能够读取文本文件,是不能读取文本之外的其他文件的。曾经尝试用缓冲字符流读取视频文件,复制后的文件根本无法使用。
下面讲字节缓冲流的使用:
字节缓冲流的底层流是字节缓冲流,将字节输入缓冲流使用read(byte[] data)读取后的数据放入字节数组中,然后使用字节输出缓冲流的write(byte[] data)方法将字节数组写入相应文件中。
代码展示如下所示:
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class BufferedStreamTest { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream("PLSQL.rar"); BufferedInputStream bis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("new02.rar"); BufferedOutputStream bos = new BufferedOutputStream(fos); byte[] data = new byte[1024 * 16]; int len = -1; long start = System.currentTimeMillis(); while((len = bis.read(data)) != -1) { bos.write(data, 0, len); } long end = System.currentTimeMillis(); System.out.println("复制花费了" + (end - start) + "毫秒"); bos.close(); bis.close(); } }
使用上述代码过程中出现过一个问题,不小心使用了BufferedInputStream的无参read()方法,无法复制数据成功。编程过程中一定要注意read()方法的调用。
针对大型文件来说,设立大的字节数据读取数据和用缓冲流读取数据速度是一样的吗?
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class BufferedInAndOutTest { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub FileInputStream fis = new FileInputStream("PLSQL.rar"); FileOutputStream fos = new FileOutputStream("new01.rar"); byte[] data = new byte[1024 * 100]; int len = -1; long start = System.currentTimeMillis(); while((len = fis.read(data)) != -1) { fos.write(data, 0, len); } long end = System.currentTimeMillis(); System.out.println("共花费了" + (end - start) + "毫秒"); fos.close(); fis.close(); } }
运行上述代码发现和使用字节缓冲流时复制文件时的速度并没有明显区别。