——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
字符流的缓冲区
缓冲区是为了提高对数据的读写效率,缓冲区要结合流才能使用,缓冲区是在流的基础上对流的功能进行了增强, 因此在创建缓冲区之前,必须要有流对象。
缓冲区对应的类没有空参数构造函数,要使用缓冲技术,只需要将字符流对象作为参数传递给缓冲对象的构造函数。
因为要对性能进行增强,在实际开发中一般都会使用缓冲区。
对应类BufferedWriter BufferedReader
缓冲技术原理:对象内封装了数组,先把数据存起来,再一次性写出去。把数组封装成对象,方便使用。
首先我们来看看BufferedWriter
package first;
/**
* 需求:在E盘根目录创建一个文件并使用字符流的缓冲区技术写入一下数据
* 思路 :缓冲区是为了提高对数据的读写效率,缓冲区要结合流才能使用,缓冲区是在流的基础上对流的功能进行了增强,
* 因此在创建缓冲区之前,必须要有流对象。
* 1.创建FileWriter对象,指定目的文件
* 2.创建BufferedWriter对象,将需要被提高效率的流对象作为参数传递给缓冲区的构造函数
* 3.把数据写入缓冲区内
* 3.调用flush方法刷新流。
* 4.调用close方法关闭缓冲区资源
*/
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterDemo {
public static void main(String args[]){
//创建一个FileWriter对象
FileWriter fw=null;
//为了提高字符写入技术,加入了缓冲技术
BufferedWriter bw=null;
try {
fw=new FileWriter("E:\\demo.txt");
//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可
bw=new BufferedWriter(fw);
bw.write("asdfghjkl");
//缓冲区中提供了一个跨平台的换行符newLine
bw.newLine();
bw.write("zxcvbnm");
//只要用到缓冲区,就要刷新
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭缓冲区,其实关闭缓冲区,也就同时关闭了缓冲区中的流对象
try {
if(bw!=null)
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我们再来看看BufferedReader
package first;
/**
* 需求:使用字符流的缓冲区技术读取E盘下的文本文件
* 思路 :缓冲区是为了提高对数据的读写效率,缓冲区要结合流才能使用,缓冲区是在流的基础上对流的功能进行了增强,
* 因此在创建缓冲区之前,必须要有流对象。
* 1.创建FileReader对象,指定目的文件
* 2.创建BufferedReader对象,将需要被提高效率的流对象作为参数传递给缓冲区的构造函数
* 3.把数据读取到缓冲区内
* 3.调用flush方法刷新流。
* 4.调用close方法关闭缓冲区资源
*/
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderDemo {
public static void main(String []args){
//创建FileReader和BufferedReader对象
FileReader fr=null;
BufferedReader br=null;
try {
//初始化,初始化BufferedReader对象时,
//只需要把FileReader对象传递到BufferedReader的构造函数
fr=new FileReader("E:\\demo.txt");
br=new BufferedReader(fr);
String line=null;
//通过字符缓冲区,一次读取文件的一行,
//readLine是就是把read读取到的一个一个的数据,存到缓冲区的一个字符串中,
//当读到行尾时,不再继续往下读。
while((line=br.readLine())!=null){
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭缓冲区,其实关闭缓冲区,也就同时关闭了缓冲区中的流对象
try {
if(br!=null)
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
注:readLine读取的是一行的有效数据,不包括换行符
readLine方法原理
无论是读取一行,还是读取多个字符,其实都是在硬盘上一个一个读取,所以最终使用的还是read方法。一次读一个字符的方法。
readLine方法就是把read读取到的一个一个的数据,存到缓冲区的一个字符串中,当读到\r\n时,这一行结束。不再继续往下读,并且\r\n不进入缓冲区的字符串中,这时返回字符串,readLine 比 read方法要高级很多,readLine的出现是在增强read方法的功能。
明白了BufferedReader类中特有的方法readLine的原理后, 现在可以自定义一个类中包含一个功能和readLine一致的方法,来模拟BufferedReader
/**
* 自定义的BufferedReader
* /
import java.io.FileReader;
import java.io.IOException;
class MyBufferedReader{
private FileReader fr;
MyBufferedReader(FileReader fr){
this.fr=fr;
}
//可以一次读一行数据的方法
public String myReadLine() throws IOException{
//定义一个临时的StringBuilder容器,原BufferedReader封装的是字符串
//最终还是要将数据变成字符串
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=fr.read())!=-1){
if(ch=='\r')//遇到\r回车 就continue
continue;
else if(ch=='\n')//遇到\n换行,就把sb转换为字符串return回去
return sb.toString();
else
sb.append((char)ch);
}
//当读结束时,要返回一个null
return null;
}
//自定义类的关闭资源的方法,
//由此也可以看出,在BufferedReader中关闭缓冲区资源就相当于关闭流资源
public void myClose() throws IOException{
fr.close();
}
}
下面我们用字符流的缓冲区技术copy一个文本文件
package first;
/**
* 需求:使用字符流的缓冲区技术copy一个文本文件
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyFileByBufferedDemo {
public static void main(String args[]){
//创建缓冲区对象
BufferedReader br=null;
BufferedWriter bw=null;
try {
//实例化缓冲区对象,这里为了代码的优化,直接把缓冲区对应的流定义为匿名的
br=new BufferedReader(new FileReader("E:\\demo.txt"));
bw=new BufferedWriter(new FileWriter("D:\\demo.txt"));
String line=null;
//每次读一行,并且把它写进目标,
//由于每次读一行时并不包含行终止符,所以写的时候要加上newLine换行
//每次写完都要刷新一次
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭缓冲区
try {
if(bw!=null)
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符流的缓冲区就到这儿