【问题标题】:Does BufferedWriter's write(String S) method actually buffer?BufferedWriter 的 write(String S) 方法是否真的缓冲?
【发布时间】:2018-08-09 06:35:45
【问题描述】:

根据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();
    }

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

【问题讨论】:

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


    【解决方案1】:

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

    由于Writer 没有任何委托目标的概念,因此不可能有任何方法委托给目标编写器而不被BufferedWriter 子类拦截,因为只有该子类知道目标。所以所有write方法以及append方法都在BufferedWriter的控制下,如果要写入的数据小于缓冲区的容量,就会缓冲。

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

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

    这可能会使你的方法过时,因为它只委托给一个已经存在的方法

    【讨论】:

      【解决方案2】:

      Writer 中的write(String str) 调用write(String str, int off, int len)BufferedWriter 中被覆盖。所以你的数据会被缓冲。

      【讨论】:

      • 有效的 Java 项目 17
      • 谢谢!遵循库中的方法调用。退房!
      猜你喜欢
      • 1970-01-01
      • 2015-07-08
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-28
      • 2011-08-02
      相关资源
      最近更新 更多