【问题标题】:When to flush a BufferedWriter何时刷新 BufferedWriter
【发布时间】:2009-05-25 21:52:59
【问题描述】:

在 Java 程序(Java 1.5)中,我有一个包装 Filewriter 的 BufferedWriter,我多次调用 write()...生成的文件非常大...

在这个文件的几行中,有些是不完整的……

每次我写东西时是否需要调用flush(但我怀疑它会效率低下)或使用另一种BufferedWriter方法或使用另一个类...?

(因为我有无数行要写,我确实想要一些非常有效的东西。) 什么是理想的“冲洗”时刻? (当我达到 BufferedWriter 的容量时)...

初始化:

try {
  analysisOutput = new BufferedWriter(new FileWriter(
      "analysisResults", true));
  analysisOutput.newLine();
  analysisOutput.write("Processing File " + fileName + "\n");
} 
catch (FileNotFoundException ex) {
  ex.printStackTrace();
} 
catch (IOException ex) {
  ex.printStackTrace();
}

写作:

private void printAfterInfo(String toBeMoved,HashMap<String, Boolean> afterMap, Location location)
  throws IOException {
    if(afterMap != null) {
      for (Map.Entry<String, Boolean> map : afterMap.entrySet()) {
        if (toBeMoved == "Condition") {
          if (1 <= DEBUG)
            System.out.println("###" + toBeMoved + " " + location + " "
                + conditionalDefs.get(conditionalDefs.size() - 1)
                + " After " + map.getKey() + " "
                + map.getValue() + "\n");

          analysisOutput.write("###" + toBeMoved + " " + location + " "
              + conditionalDefs.get(conditionalDefs.size() - 1)
              + " After " + map.getKey() + " " + map.getValue()
              + "\n");
        } else {
          if (1 <= DEBUG)
            System.out.println("###" + toBeMoved + " " + location + " "
                + map.getKey() + " After " 
                + map.getValue() + "\n");
          if (conditionalDefs.size() > 0)
            analysisOutput.write("###" + toBeMoved + " " + location + " "
                + conditionalDefs.get(conditionalDefs.size() - 1) + " "
                + map.getKey() + " After " + map.getValue()
                + "\n");
          else
            analysisOutput.write("###" + toBeMoved + " " + location + " " + map.getKey() + " After " + map.getValue() + "\n");


        }
      }
    }

我刚刚发现不完整的行是“处理文件”之前的行...所以当我从一个我分析的文件切换到另一个文件时会发生这种情况...

结束:

dispatch(unit);

try {
  if (analysisOutput != null) {
    printFileInfo();
    analysisOutput.close();
  }
} 
catch (IOException ex) {
  ex.printStackTrace();
}

有时printFileInfo打印出来的信息不会出现在结果文件中……

【问题讨论】:

  • 如果有些不完整,您是否有多个线程写入它? IIRC BufferedWriter 不是线程安全的,所以这可能是一种解释,但它不必“手动刷新”以腾出更多空间,它自己会处理。
  • 如果你不确定你的问题是否清楚,也许提供一个代码示例或输出示例来澄清。
  • 它实际上是线程安全的(尽管 Writer 装饰器在同意锁定什么对象方面存在问题)。
  • 如何确定这是线程安全的?我正在写一个静态文件并使用 make -j (我猜这是多线程的......)
  • 我会在 printFileInfo() 方法中寻找错误。

标签: java io


【解决方案1】:

BufferedWriter 在填满缓冲区时已经刷新。来自BufferedWriter.write的文档:

通常此方法将给定数组中的字符存储到此流的缓冲区中, 根据需要将缓冲区刷新到底层流

(强调我的。)

BufferedWriter 的要点基本上是将大量的小写入合并为少得多的大写入,因为这通常更有效(但编写代码更痛苦)。你不应该做任何特别的事情来让它正常工作,除了确保你用它完成刷新它 - 并调用 close() 将执行此操作并刷新/无论如何关闭底层作家。

换句话说,放松——只需要写,写,写,然后关闭 :) 通常您唯一需要手动调用flush 的情况是,如果您现在真的非常需要将数据保存在磁盘上。 (例如,如果您有一个永久记录器,您可能希望每隔一段时间刷新一次,这样读取日志的人就无需等到缓冲区已满才能看到新的日志条目!)

【讨论】:

  • 经过测试和批准。逐行写入 10Mb 的数字:每行写入后刷新 - 需要 7 秒,不刷新 - 4 秒。
【解决方案2】:

理想的刷新时刻是在文件关闭之前,您需要另一个程序读取文件以查看已写入的数据。在许多情况下,这永远不会。

【讨论】:

  • 即使 BufferedWriter 很大...我也不必在中间阶段做?
  • 如果缓冲区填满,它会将其内容写入磁盘。 BufferedWriter API 旨在替代 FileWriter,但在文件关闭之前使用数据除外。
【解决方案3】:

如果你有一个循环交替initprintAfterInfo,我猜你的问题是你没有close 你的作家在同一个文件上创建一个新的之前。您最好创建一次BufferedWriter,并在所有处理结束时将其关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2017-09-15
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多