写入文件时出现奇怪的行为

7

我正在尝试一些基本的Java I/O操作,我试图运行下面的代码:

public static void main(String[] args) {
    File file = new File("fileWrite2.txt"); // create a File object
      try {
    FileWriter fr = new FileWriter(file);
    PrintWriter pw = new PrintWriter(file); // create a PrintWriter that will send its output to a Writer
    BufferedWriter br =  new BufferedWriter(fr);
    br.write("sdsadasdsa");br.flush();br.append("fffff");br.flush();
    pw.println("howdy"); // write the data
    pw.println("folks");
    pw.flush();
    pw.close();
    } catch (IOException e) {
       e.printStackTrace();
    }
}

当我运行上述代码时,将在创建的文件中获得以下输出:
howdy
folks
f

有人能解释一下为什么“f”出现在最后一行吗?
3个回答

7

f来自于br.append("fffff");中剩余的字符串,这个字符串是由BufferedWriter写入文件中的。

由于BufferedWriterPrintWriter都向同一个文件中写入内容,PrintWriter写入的内容会覆盖BufferedWriter写入的内容。

但似乎PrintWriter写入的字节数比BufferedWriter写入的数据少1,因此你会得到f

如果你将br.append("fffff");改为br.append("ffffg");,你会发现现在剩下了g。或者将pw.println("folks");改为pw.println("folks1");,你会看到之前写入的数据现在被PrintWriter完全覆盖了。

由于同一个文件对象有两个不同的写入器,这就是问题的原因所在,导致了所有的混乱。正如@Boris所指出的那样,只需为文件对象设置一个写入器即可。
注意:另一个有趣的测试是将第二个br.flush();移动到pw.flush();之后。
// br.flush(); // moved from here
pw.println("howdy"); // write the data
pw.println("folks");
pw.flush();
br.flush(); // to here

7
简而言之,每个文件只使用一个“Writer”。 - Boris the Spider
谢谢。已更新答案并提到了这一点! :) - Rahul
@R.J - 尝试了您的建议,并将第二个br.flush()移动到pw.flush()之后。现在输出更改为:howdy folfffff,有人能解释一下吗?我们只有在flush()流之后,写入器才会写入文件吗? - Twaha Mehmood

3
你正在使用 BufferedWriter 写入 15 个字符,代码如下:`
br.write("sdsadasdsa");
br.flush();
br.append("fffff");`

但是当你使用printWriter进行写入时,它会覆盖本次写入的文件内容。

pw.println("howdy"); // write the data
pw.println("folks");

这段文字涉及到IT技术,其中提到了一个长度为10个字符的文本,其中包含两个换行符\n。由于我们使用println函数,在Windows系统中\n会被转化为\r\n,因此总共需要14个字节来存储这段文本。因此还剩下1个字符,即f。


2
在您的代码中执行以下步骤。
1. 当
br.write("sdsadasdsa");br.flush();br.append("fffff");br.flush();

被执行。

文件内容将会是

sdsadasdsafffff

在调用 pw.println("howdy"); 时,会输出字符串 "howdy"。

字符串howdy将覆盖前五个字符sdsad,并以换行符结束该行。在文本中,需要使用两个字符\r\n表示一个换行符,这将覆盖另外两个字符。接下来文件内容如下:

howdy

dsafffff

在执行 pw.println("folks"); 时,是第3步。

由于在第2步中没有调用 flush() 方法。字符串 folks 将覆盖文件中的第二行内容,并换行以覆盖另外2个字符。

然后,以下内容将存储在文件中:

howdy

folks

f

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接