根据java文档,
通常,Writer将其输出立即发送到底层字符或字节流。除非需要提示输出,否则它是建议将BufferedWriter封装在任何write()的Writer周围。操作可能是昂贵的,比如FileWriters和OutputStreamWriters。例如,
printwwriter out = new printwwriter (new BufferedWriterFileWriter("foo.out"))),
将printwwriter的输出缓冲到文件中。没有缓冲,每次调用print()方法都会导致字符被删除转换成字节,然后立即写入
但是下面的代码看起来好像FileWriter在刷新到输出流之前也缓冲了字节。
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class TestFileWriter {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
FileWriter fileWriter= new FileWriter("test.txt");
File file=new File("test.txt");
for (int i=0; i<1000; i++) {
fileWriter.write("a very long string, a very long string, a very long string, a very long string, a very long stringn");
if(i%50 == 0)
System.out.print("file size=" + file.length()+",");
}
fileWriter.close();
System.out.println("file size=" + file.length());
}
}
输出: -
file size=0,file size=0,file size=8192,file size=8192,fileSize =16384,file Size =24576,file Size =24576,file Size =32768,fileSize =32768,文件大小=40960,文件大小=49152,文件大小=49152,文件大小=49152Size =57344,file Size =57344,file Size =65536,file Size =73728,fileSize =73728,文件大小=81920,文件大小=81920,文件大小=90112,文件大小= 99000
为什么数据在被写入时没有被写入文件?
如果添加
fileWriter.flush();
可以看到每行的大小都改变了。这意味着正在发生缓冲。
使用调试器我跟踪这到StreamEncoder,它在Oracle JDK中没有源代码,但可以在线使用
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/cs/StreamEncoder.javaprivate static final int DEFAULT_BYTE_BUFFER_SIZE = 8192;
private StreamEncoder(OutputStream out, Object lock, CharsetEncoder enc) {
// some deleted
if (ch == null) {
bb = ByteBuffer.allocate(DEFAULT_BYTE_BUFFER_SIZE);
}
}
如你所见,编码器有它自己的缓冲区。
注意:由于这是一个内部类,它可能会在未来改变,并且它可能不会在所有平台上都这样做。
您对FileWriter的假设似乎是正确的。
引用:
[1] http://docs.oracle.com/javase/6/docs/api/java/io/FileWriter.html该类的构造函数假定默认字符编码和默认字节缓冲区大小是可接受的。
[2] java - FileWriter使用缓冲区吗?(它的行为就像它在我的例子)
缓冲在Java中应用于底层流写入,而不是FileWriter级别。