java.io.FileWriter 是为一次性使用而设计的吗?

Is java.io.FileWriter designed only for a single use?

我正在构建一个不断写入同一个文件的程序,使用 java.io.FileWriter

在 运行 期间,每当我需要更新文件时,我都会调用 writes "properly" 的方法并使用 class 级别的 FileWriter。问题开始于第二次 .write 调用,当 FileWriter 开始 appending 到文件,而不是 overwriting 它。

public class Example {
    private FileWriter fw = new FileWriter("file's path", false);

    public void writeToFile(String output) {
        fw.write(output);
        fw.flush();
    }
}

我怀疑 FileWriter 的 "memory" 以某种方式保留了它之前写入的数据,但我不想在每次调用时关闭并初始化它,因为这看起来很浪费。

  1. 每次 .write 通话后我什至需要 .flush 通话吗?
  2. 除了初始化 FileWriter 并在每次调用时 .close-ing 之外,我还有其他选择吗?

(我尝试查看较旧的问题,但它们似乎都处理 不会 附加的 FileWriters,或理论上的 FileWriter.flush 解释)

Writer(其中 FileWriter 是一个子类)documented 在面向流的模型中工作,例如随机访问模型。通过相同 Writer 实例的连续写入始终附加。要覆盖现有文件,您需要每次构造一个新的 FileWriter 实例。无论如何,这实际上是一个相当便宜的操作。

The problem starts on the second .write call, when the FileWriter starts appending to the file, instead of overwriting it.

是的,你有一个开放的作家。写入该 writer 只会将 additional 文本写入文件 - 就像在 OutputStream 上多次调用 write 会将附加数据写入流而不是覆盖每次通话的现有数据。想象一下,如果您的代码有:

fw.write("first");
fw.flush();
fw.write("second");
fw.flush();

您是否希望用 "second" 替换文件的全部内容?我不会 - 如果你调用 writeToFile 两次就会发生这种情况。

如果您希望每次调用 writeToFile 完全替换文件的内容,您应该在方法内创建一个新的编写器,写入,然后关闭编写器。

就我个人而言,无论如何我都会避免使用 FileWriter,因为它使用平台默认编码编写,这不是很好。

我会使用 Files.write which will write a sequence of lines to a file, or Files.newBufferedWriter 为多个写入调用创建编写器。

由于您为构造函数的第二个参数传递了 false,因此 FileWriter 将以 "rewrite" 模式启动。但是,只要您继续使用相同的 FileWriter 对象,它就会继续附加到同一个文件。

您在 class 的初始值设定项中创建了 FileWriter,之后再也不会用另一个 FileWriter 替换它。这就是它一直附加到文件的原因。

如果您需要在某个时候替换文件,您有几种选择:

  • 替换 FileWriter 实例 - 您可以关闭旧的 FileWriter,然后创建一个新实例。新编写器将覆盖现有文件,或者
  • 使用 RandomAccessFile - 这个 class 让你 "rewind" 到文件的开头。