【问题标题】:Strange behavior in writing to file写入文件的奇怪行为
【发布时间】:2013-11-27 02:38:19
【问题描述】:

我正在尝试一些基本的 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'出现在最后一行?

【问题讨论】:

    标签: java file-io io printwriter bufferedwriter


    【解决方案1】:

    您正在通过这样做在bufferedwriter 上写入 15 个字符 `

    br.write("sdsadasdsa");
    br.flush();
    br.append("fffff");`
    

    但是当你在 printWriter 上写入时,它会覆盖文件的内容 这次你在写

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

    只有 10 个字符,两个新行 \n 占用 2 个字节,因为我们使用 println 因为 Windows 中的 \n 将转换为 \r\n 。所以总共14个。 所以剩下1个字符是f

    【讨论】:

      【解决方案2】:

      在您的代码中执行以下步骤。

      1 当

      br.write("sdsadasdsa");br.flush();br.append("fffff");br.flush();
      

      被执行。

      文件内容为

      sdsadasdsafffff
      

      2 当 pw.println("你好");正在打电话。

      String howdy 覆盖前 5 个字符 sdsad 并且新行终止该行。在txt中,需要2个字符\r\n,这样会覆盖另外2个字符。那么文件内容如下:

      howdy
      
      dsafffff
      

      3 当 pw.println("伙计们"); 被执行。

      因为在步骤#2 中没有调用 flush() 方法。 String folks 将覆盖文件中的第二行内容。和一个新行来覆盖另外 2 个字符。

      那么下面的内容会被保存到文件中:

      howdy
      
      folks
      
      f
      

      【讨论】:

        【解决方案3】:

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

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

        但似乎没有。 PrintWriter 写入的字节数不足 1 以完全覆盖 BufferedWriter 写入的数据,因此您得到 f

        如果您将这个br.append("fffff"); 更改为br.append("ffffg");,您可以看到g 现在剩下了。或者,将pw.println("folks"); 更改为pw.println("folks1"); 将显示之前写入的数据现在完全被PrintWriter 覆盖。

        所有这些混乱都是因为同一文件对象有 2 个不同的写入者,这是问题的原因。正如@Boris 指出的那样,文件对象只有 1 个编写器。

        注意:要测试的另一个有趣的事情是将第二个 br.flush(); 移到 pw.flush(); 之后。

        // br.flush(); // moved from here
        pw.println("howdy"); // write the data
        pw.println("folks");
        pw.flush();
        br.flush(); // to here
        

        【讨论】:

        • 简而言之,每个文件只能使用一个Writer
        • 谢谢。更新了答案以提及! :)
        • @R.J - 尝试了你的建议并移动了第二个 br.flush();在 pw.flush(); 之后。输出现在变为:你好 folfffff 谁能解释一下? Writers 是否只在我们 flush() 流之后才写入文件?
        猜你喜欢
        • 2016-12-15
        • 2020-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多