提要
01 IO流(BufferedWriter)
02 IO流(BufferedReader)
03 IO流(通过缓冲区复制文本文件)
04 IO流(readLine的原理)
05 IO流(MyBufferedReader)
06 IO流(装饰设计模式)
07 IO流(装饰和继承的区别)
01 IO流(BufferedWriter)
字符流的缓冲区
缓冲区的出现提高了对数据的读写效率。
对应类
BufferedWriter
BufferedReader
缓冲区要结合流才可以使用
在流的基础上对流的功能进行了加强
/*
缓冲区的出现是为了提高流的操作效率,
所以在创建缓冲区之前,必须要先有流对象。 该缓冲区提供了一个跨平台的换行方法 newLine()
*/
import java.io.*;
public class BufferedWriterDemo
{
public static void main(String[] args)throws IOException
{
//创建一个字符写入流对象
FileWriter fw=new FileWriter("buf.txt"); //为了提高字符写入流效率,加入了缓冲区
//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可
BufferedWriter bufw=new BufferedWriter(fw); for(int x=1;x<5;x++)
{
bufw.write("abcde"+x);
//写入一个行分隔符,是跨平台的
bufw.newLine();
//记住,只要用到缓冲区,就要记得刷新
bufw.flush();
} //其实,关闭缓冲区,就是在关闭缓冲区流中的对象
bufw.close(); }
}
02 IO流(BufferedReader)
/*
字符读取缓冲区
该缓冲区提供了一个一次读一行的方法,readLine()
*/
import java.io.*;
public class BufferedReaderDemo
{
public static void main(String[] args)throws IOException
{
//创建一个读取流对象和文件相关连
FileReader fr=new FileReader("buf.txt"); //为了提高效率,加入缓冲技术,
//将字符读取流对象作为参数传递给缓冲对象的构造函数
BufferedReader bufr=new BufferedReader(fr); String line; while((line=bufr.readLine())!=null)
{
System.out.println(line);
} bufr.close();
}
}
03 IO流(通过缓冲区复制文本文件)
注意:readLine方法只返回回车符前面的部分,并不返回回车符。
/*
通过缓冲区复制一个.java文件
*/
import java.io.*;
public class CopyTextByBuf
{
public static void main(String[] args)
{
BufferedReader bufr=null;
BufferedWriter bufw=null; try
{
bufr=new BufferedReader(new FileReader("BufferedWriterDemo.java"));
bufw=new BufferedWriter(new FileWriter("buffferWriter_Copy.txt")); String line;
while((line=bufr.readLine())!=null)
{
bufw.write(line);
bufw.newLine();
bufw.flush();
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败!");
}
finally
{
try
{
if(bufr!=null)
bufr.close();
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败!");
}
try
{
if(bufw!=null)
bufw.close();
}
catch (IOException e)
{
throw new RuntimeException("写入关闭失败!");
}
}
}
}
04 IO流(readLine的原理)
无论是读一行,或者读取多个字符,其实最终都是在硬盘上一个一个读取,所以最终使用的还是read方法一次一次读取。
05 IO流(MyBufferedReader)
/*
明白了BufferedReader类中特有方法reaLine的原理后,
可以自定义一个类中包含一个功能和readLine一致的方法。
来模拟一下BufferedReader */
import java.io.*;
class MyBufferedReader
{
private FileReader r;
MyBufferedReader(FileReader r)
{
this.r=r;
}
//可以一次读一行数据的方法
public String myReadLine() throws IOException
{
//定义一个临时容器,原BufferReader封装的是字符数组
//为了演示方便,定义一个StringBuilder容器
//因为最终还是要将数据变成字符串 StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=r.read())!=-1)
{
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
public void myClose()throws IOException
{
r.close();
}
} public class MyBufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr=new FileReader("buf.txt"); MyBufferedReader myBuf=new MyBufferedReader(fr);
String line=null;
while((line=myBuf.myReadLine())!=null)
{
System.out.println(line);
}
myBuf.myClose(); }
}
06 IO流(装饰设计模式)
/*
装饰设计模式:
当想要对已有的对象进行功能增强时,
可以定义类,将已有对象传入,基于已有功能,并提供加强功能
那么自定义的这个类就成为装饰类 装饰类通常会通过构造方法接收被装饰的的对象
并基于被装饰对象的功能,提供更强的功能
*/
class Person
{
public void chiFan()
{
System.out.println("吃饭");
}
}
class SuperPerson
{
private Person p;
public SuperPerson(Person p)
{
this.p=p;
}
public void superChiFan()
{
System.out.println("开胃酒");
p.chiFan();
System.out.println("甜点");
System.out.println("来一根"); }
}
public class PersonDemo
{
public static void main(String[] args)
{
SuperPerson sp=new SuperPerson(new Person());
sp.superChiFan(); }
}
07 IO流(装饰和继承的区别)
用继承体系来实现功能增强
MyReader//专门用于读取数据的类
|--MyTextReader
|--MyBufferTextReader
|--MyMediaTextReader
|--MyBufferMediaReader
|--MyDataReader
|--MyBufferDataReader
class MyBufferReader
{
MyBufferReader(MyTextReader text)
{}
MyBufferReader(MyMediaTextReader media text)
{}
}
上面这个类的扩展性很差
找到其参数的共同类型,通过多态的形式,可以提高扩展性
class MyBufferReader extends MyReader
{
MyBufferReader(MyReader r)
{}
}
用装饰来实现功能增强
MyReader//专门用于读取数据的类
|--MyTextReader
|--MyMediaReader
|--MyDataReader
|--MyBufferReader
装饰模式比继承要灵活,避免了继承体系的臃肿
而且降低了类与类之间的关系。
装饰类因为增强已有对象,具备的功能和已有对象是相同的,
只不过是提供了更强的功能
所以装饰类和被装饰类通常是属于一个体系的