在写这篇笔记时我在想BufferedWriter用缓冲,每次刷新缓存(flush()方法)就行,我于是就有个疑问:比如:缓存大小为1024,当我已通过write
(char[] cbuf, int off, int len)
方法在缓存中保存1000个字符,那么当再次调用write方法写入25个时,最后的字符会不会丢呢?经代码验证并没有丢失,那是什么原因?带着疑问你看下面我的日记你就会明白为什么?
1. 首先认识一下
Writer ,它是抽象类,其中有一个抽象方法write(char[] cbuf, int off, int len)
和一个具体实现了的
write(
String str, int off, int len)
,其实
write(
String str)
里面也是调用了
write(char[] cbuf, int off, int len)
;而这个方法是抽象的,所以取决于继承Writer抽象类的具体实现类对抽象方法的实现。
2.
BufferedWriter
是抽象类Writer的实现类,并实现了抽象方法
write(char[] cbuf, int off, int len)
;
这个实现中添加了如果添加的字符数组的大小超过了默认缓存的大小(8096或你设置的大小),则采取先刷新缓存flushBuffer的方法,flushBuffer中先将缓存中的字符写出,在清空缓存,之后循环写入伪代码如下:
nChars:缓存数组大小
nextChar:缓存数组现在指针,即已用
//…..
Int b=off,t=off+length,
While(b<t) {
1、Int min = 此时缓存剩余的大小(nChars-nextChar)和t-b的最小值
2、将min个字符复制到缓存中
3、b+=min;nextChar+=min( 缓存指针也下移min位);
4、if (nextChar>=nChars){
flushBuffer();
}
}
缓存方法伪码如下:
flushBuffer(){
//……
out.write(cb,0,nextChar);
nextChar =0;
}
BufferedWriter中的write(
String str, int off, int len)
底层也是调用BufferedWriter中的
write(char[] cbuf, int off, int len)
,都不会出现缓存溢出导致的数据丢失问题,大可放心使用
3. BufferedWriterd的构造方法中还要有Writer的具体实现类,一般如:OutputSteamWriter或FileWriter等字符流,
BufferedWriter中的write方法的实具体现实际是BufferedWriter在创建实例时所传递参数对象(字符流,如上面FileWriter)的write的方法,以下是常用的应用举例。
共举2个例子如下:
1) BuffferedWriter bw = new BufferedWritter(new OutputStreamWriter(FileOutputStream(fileName),”utf-8”));
OutputStreamWriter中的write方法大致如下:
se.write(char[] cbuf, int off, int len)
其中se是StreamEncoder的实例,其实不止OutputStreamWriter的Write方法,大部分的方法都是调用StreamEncoder的同名称的方法,其实StreamEncoder也是继承了Writer的实现类,它在OutputStreamWriter中就是个代理。
(主要是字符和字节之间的过渡,起到桥梁的作用。)强调一下
FileOutputStream中的读写方法都是native方法,直接通过JNI操作系统资源
2) BuffferedWriter bw = new BufferedWritter(FileWriter(fileName));
其中FileWriter是OutputStreamWriter
的子类,FileWriter的构造方法伪码如下:
public FileWriter(file)throws IOException{
super(new FileOutputStream(file))
}
从上面的代码可以看出其实都是通过OutputStreamWriter这个桥梁去完成的
不知我的解释是否能全面解答你的疑问,如有笔误请指教!