12、2字符流
今天老师上课首先回顾了昨天讲的字节流的知识点,接下来又给我们讲了字符流的高速缓存以及它里面readLine()方法的功能和原理。
一、 缓冲的字符流BufferedReader/BufferedWriter
1、采用缓冲处理是为了提高效率,如果没有缓存,例如FileReader对象,每次调用read()方法进行读操作时,都会直接去文件中读取字节,转换成字符并返回,这样频繁的读取文件效率很低。
2、缓冲的字符流的出现提高了对流的操作效率,原理就是将数组进行封装。
3、在使用缓冲的字符流对象时,缓冲的存在是为了增强流的功能,因此在建立缓冲的字符流对象时,要先有流对象的存在。
例如:public BufferedReader(Reader in);
Public BufferedReader(Reader in,int sz);
Public BufferedWriter(Writer out);
Public BufferedWriter(writer out,int sz);
BufferedReader的特有方法:public String readLine();//一次读一行,到行标记时,将行标记之前的字符数据作为字符串返回。当读到末尾时,返回null。
BufferedWriter的特有方法:public void newLine();//写出平台相关的行分隔符来标记一行的终止。Windows平台下为’\n’。
使用缓冲的字符流时其实就是使用流对象的方法,只不过加入了数组,对数据进行了临时存储,为了提高操作数据的效率
二、 readLine()的原理
该方法用的还是与缓冲的字符流相关联的流对象的read()方法,只不过,每一次读到一个字符,先不进行具体操作,先进行临时存储,当读取到回车标记时,将临时容器中存储的数据一次性返回。
该方法的原理代码如下:
import java.io.*;
public class MyBafferedIODemo {
//属性
private Reader r;
//构造方法
public MyBafferedIODemo(Reader r){
this.r=r;
}
//readLine()方法,增加一个缓冲区,然后调用r对象的read()读取的字符放到缓冲区,当我读到行标记时,把缓冲区的字符转换成字符串返回;
public String readLine(){
StringBuffer strB=new StringBuffer();
int ch=0;
try {
while((ch=r.read())!=-1){
if(ch=='\r')
continue;
if(ch=='\n'){
return new String(strB);
}else{
strB.append((char)ch);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(strB.length()!=0)
return new String(strB);
return null;
}
//close()方法
public void close(){
try {
r.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试类如下:
import java.io.*;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyBafferedIODemo mbr=null;
FileReader fr=null;
try {
fr=new FileReader("res/demo.txt");
mbr=new MyBafferedIODemo(fr);
String str=mbr.readLine();
while(str!=null){
System.out.print(str);
str=mbr.readLine();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
fr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
三、 装饰设计模式和继承有什么区别
1. 装饰设计模式比继承有更好的灵活性
需求:想要对数据的操作提高效率,就用到了缓冲技术。
如图所示:
假设writer有一个两个子类mediawriter与textWriter,在这两个子类中重写父类的write方法即可。
|
节点流 FileReader |
read() |
处理流 BufferedReader |
readLine() |
今天的实例如下:
1、缓冲输入流:import java.io.*;
public class BufferedIODemo {
public static void main(String[] args){
FileWriter fw=null;
BufferedWriter bw=null;
try {
fw=new FileWriter("res/demo.txt");
bw=new BufferedWriter(fw);
bw.write("hello");
bw.newLine();
bw.write("java");
bw.newLine();
bw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(bw!=null){
try {
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
2、缓冲输出流:
package com.hbsi.IO;
import java.io.*;
public class BufferedIODemo2 {
public static void main(String[] args){
FileReader fr=null;
BufferedReader br=null;
try {
fr=new FileReader("res/demo.txt");
br=new BufferedReader(fr,255);
String str=null;
try {
while((str=br.readLine())!=null){
System.out.print(str);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// str=br.readLine();
// while(str!=null){
// System.out.print(str);
// str=br.readLine();
// }
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if(br!=null){
try {
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}