前几节我们学习了文件字节输入输出流和文件字符输入输出流,这一节我们学习一个新的概念——缓冲流。那什么叫做缓冲流呢?缓冲流又能起到什么作用呢?
在Java中,我们把BufferedReader和BufferedWriter类创建的对象称为缓冲输入输出流,二者增强了读写文件的能力。比如,Sudent.txt是一个学生名单,每个姓名占一行。如果我们想读取名字,那么每次必须读取一行,使用FileReader流很难完成这样的任务,因为,我们不清楚一行有多少个字符,FileReader类没有提供读取一行的方法。
Java提供了更高级的流:BufferedReader流和BufferedWriter流,二者的源和目的地必须是字符输入流和字符输出流。因此,如果把文件字符输入流作为BufferedReader流的源,把文件字符输出流作为BufferedWriter流的目的地,那么,BufferedReader和BufferedWriter类创建的流将比字符输入流和字符输出流有更强的读写能力。比如,BufferedReader流就可以按行读取文件。
BufferedReader类和BufferedWriter的构造方法分别是:
BufferedReader(Readerin);BufferedWriter(Writerout);
BufferedReader流能够读取文本行,方法是readLine()。通过向BufferedReader传递一个Reader子类的对象,比如FileReader的实例,来创建一个BufferedReader对象,例如:
FileReaderinOne=newFileReader(Student.txt);BufferedReaderinTwo=BufferedReader(inOne);
然后inTwo流调用readLine()方法中读取Student.txt,例如:
StringstrLine=inTwo.readLine();
类似地,可以将BufferedWriter流和FileWriter流连接在一起,然后使用BufferedWriter流将数据写到目的地,例如:
FileWritertofile=newFileWriter(hello.txt);BufferedWriterout=BufferedWriter(tofile);
然后out使用BufferedReader类的方法write(String s,int off,int len)把字符串s写到hello.txt中,参数off是s开始处的偏移量,len是写入的字符数量。
另外,BufferedWriter流有一个独特的向文件写入一个回行符的方法:
newLine();
可以把BufferedReader和BufferedWriter称为上层流,把它们指向的字符流称为底层流,Java采用缓存技术将上层流和底层流连接。底层字符输入流首先将数据读入缓存,BufferedReader流再从缓存读取数据;BufferedWriter流将数据写入缓存,底层字符输出流会不断地将缓存中的数据写入到目的地。当BufferedWriter流调用flush()刷新缓存或调用close()方法关闭时,即使缓存没有溢出,底层流也会立刻将缓存的内容写入目的地。
注意:关闭输出流时要首先关闭缓冲输出流,然后关闭缓冲输出流指向的流,即先关闭上层流再关闭底层流。在编写代码时只需关闭上层流,那么上层流的底层流将自动关闭。
例如:
由英语句子构成的文件english.txt如下,每句占一行:
Thearrowmissedthetarget.Theyrejectedtheuniondemand.Wheredoesthisroadgoto?
要求按行读取english.txt,并在该行的后面加上该英语句子中含有的单词数目,然后再将该行写入到一个名字为englishCount.txt的文件中,代码如下:
importjava.io.*;importjava.util.*;publicclassMain{publicstaticvoidmain(Stringargs[]){FilefRead=newFile(english.txt);FilefWrite=newFile(englishCount.txt);try{Writerout=newFileWriter(fWrite);BufferedWriterbufferWrite=newBufferedWriter(out);Readerin=newFileReader(fRead);BufferedReaderbufferRead=newBufferedReader(in);Stringstr=null;while((str=bufferRead.readLine())!=null){StringTokenizerfenxi=newStringTokenizer(str);intcount=fenxi.countTokens();str=str+句子中单词个数:+count;bufferWrite.write(str);bufferWrite.newLine();}bufferWrite.close();out.close();in=newFileReader(fWrite);bufferRead=newBufferedReader(in);Strings=null;System.out.println(fWrite.getName()+内容:);while((s=bufferRead.readLine())!=null){System.out.println(s);}bufferRead.close();in.close();}catch(IOExceptione){System.out.println(e.toString());}}}
运行结果如下:
englishCount.txt内容:Thearrowmissedthetarget.句子中单词个数:5Theyrejectedtheuniondemand.句子中单词个数:5Wheredoesthisroadgoto?句子中单词个数:6