java.io.FileWriter是否在写入输出流之前缓冲字节

时间:2014-05-02 09:33:24

标签: java file-io fileoutputstream filewriter bufferedwriter

根据java docs,

  

通常,Writer会立即将其输出发送到底层   字符或字节流。除非需要提示输出,否则它是   建议将BufferedWriter包装在任何write()的Writer周围   操作可能很昂贵,例如FileWriters和OutputStreamWriters。   例如,

     

PrintWriter out = new PrintWriter(new BufferedWriter(new   FileWriter的( “foo.out”)));

     

会将PrintWriter的输出缓冲到文件中。没有缓冲,   每次调用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 string\n");
        if(i%50 == 0)
            System.out.print("file size=" +  file.length()+",");

    }
    fileWriter.close();
    System.out.println("file size=" +  file.length());

}

}

输出: -

  

文件大小= 0,文件大小= 0,文件大小= 8192,文件大小= 8192,文件   size = 16384,文件大小= 24576,文件大小= 24576,文件大小= 32768,文件   size = 32768,文件大小= 40960,文件大小= 49152,文件大小= 49152,文件   size = 57344,文件大小= 57344,文件大小= 65536,文件大小= 73728,文件   size = 73728,文件大小= 81920,文件大小= 81920,文件大小= 90112,文件   大小= 99000

为什么数据写入时不会写入文件?

2 个答案:

答案 0 :(得分:5)

如果你添加

fileWriter.flush();

你可以看到每一行的尺寸都发生了变化。这意味着正在进行缓冲。

使用调试器我将其跟踪到StreamEncoder,它在Oracle JDK中没有源但可以在线获得

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/cs/StreamEncoder.java

private 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);
    }
}

如您所见,编码器有自己的缓冲区。

注意:由于这是一个内部类,它可能会在将来发生变化,并且可能不会在所有平台上以这种方式运行。

答案 1 :(得分:2)

您对FileWriter的假设似乎是正确的。

参考文献:

  

此类的构造函数假定默认字符编码和默认字节缓冲区大小是可接受的。

[1] http://docs.oracle.com/javase/6/docs/api/java/io/FileWriter.html

[2] java - Does FileWriter use a buffer? (it acts like it does in my example)

缓冲应用于Java中的基础Stream Writing,而不是FileWriter级别。