BufferedWriter的write(String S)方法实际上是缓冲区吗?

时间:2018-03-01 08:30:23

标签: java performance java-8 file-handling bufferedwriter

根据Java SE 8 Documentation,BufferedWriter类有自己的以下方法(w.r.t写入数据):

write(char[] cbuf, int off, int len)
write(int c)
write(String s, int off, int len)

正如我通过检查此类的源代码确认的那样,它不会覆盖Writer的write(String s)方法。它只是继承了它。

我的问题是,给出以下代码:

public static void SaveTextToFile(String fileName, String data, boolean append) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter(new File(fileName)));
        bw.write(data);
        bw.close();
    }

在写入文件之前,数据是否会被实际缓冲?如果不是,在哪些情况下会发生缓冲?

2 个答案:

答案 0 :(得分:6)

Writer来电write(String str)中{p> write(String str, int off, int len),其中 BufferedWriter中被覆盖。所以你的数据将被缓冲。

答案 1 :(得分:2)

关于哪种方法BufferedWriter覆盖的推理是没有意义的。 Writer类的所有非抽象方法都是根据其他方法实现的,最终以其中一个抽象方法结束,因为Writer本身没有实现任何实际的写作逻辑(怎么可能?)。

由于Writer没有任何委托目标的概念,因此只有该子类知道目标,才能在没有BufferedWriter子类拦截的情况下将任何方法委托给目标编写器。因此,如果要写入的数据小于缓冲区的容量,则所有write方法以及append方法都在BufferedWriter的控制下并将缓冲。 / p>

那就是说,在你的例子中,

BufferedWriter bw = new BufferedWriter(new FileWriter(new File(fileName)));
bw.write(data);
bw.close();

缓冲没有优势,因为缓冲区将在随后的close()操作中正确刷新。因此,在最好的情况下,data大于缓冲区并且您只是不必要地创建了BufferedWriter实例。但是如果data小于缓冲区,那么在实际写入数据之前,您还会从data执行不必要的复制操作到缓冲区。

对于写一个项目,缓冲是没有意义的。除此之外,提供一个实际被忽略的append参数是非常危险的,假装一个不存在的功能,特别是当这会导致意外覆盖目标文件中的现有数据时。此外,您应该使用try-with-resources构造来安全地关闭编写器:

public static void SaveTextToFile(String fileName, String data, boolean append)
                                                                throws IOException {
    try(Writer w = new FileWriter(fileName, append)) {
        w.write(data);
    }
}

// use StandardOpenOption.APPEND to append
public static void SaveTextToFile(String fileName, String data, OpenOption... o)
                                                                throws IOException {
    Files.write(Paths.get(fileName),
                Collections.singleton(data), Charset.defaultCharset(), o);
}

可能会使您的方法过时,因为它只委托给现有的方法