Java I/O 字符串已写入但未显示在文件中的问题

Java I/O problem the string was written but didn't show on the file

我创建了一个 I/O class 来读取一些文本并将其附加到文件中。

我以为它已经写好了,但由于某些原因它没有显示在文件中 - 虽然程序可以识别它。

文件 TestResult.csv 位于程序文件夹内的 src/main/resources 文件夹中。

我从 HowToDoInJava 上的教程学习了如何打开和阅读它:Read a file from the ‘resources’ folder

我的代码

前几行代码与网站中的示例非常相似。

import java.io.*;
import java.nio.file.Files;
import java.io.FileWriter;

public class ReadResourceFileDemo {

    public static void main(String[] args) throws IOException {
        //open file
        ClassLoader classLoader = IOLab.class.getClassLoader();
        File file = new File(classLoader.getResource("TestResult.csv").getFile());

        //append
        try (FileWriter fw=new FileWriter(file, true)) {
            fw.append("\nJulie,Brown,100,A");
            String content = new String(Files.readAllBytes(file.toPath()));
            System.out.println(content);
        }
    }
}

我在 TestResult.csv

中得到了什么
Alex,Smith,99,A
Jolene,Schmidt,100,A
Mackinzie,Jensen,86,B

目标是将字符串附加到 TestResult.csv

在我 运行 之后 第一次 结果是:

Alex,Smith,99,A
Jolene,Schmidt,100,A
Mackinzie,Jensen,86,B

然后我 运行 再次 第二次 并得到:

"C:\Program Files\Java\jdk-16.0.2\bin\java.exe" "-javaagent:C:\Program 
Files\JetBrains\IntelliJ IDEA 2021.2.1\lib\idea_rt.jar=56365:C:\Program 
Files\JetBrains\IntelliJ IDEA 2021.2.1\bin" -Dfile.encoding=UTF-8 -classpath 
C:\Users\tuant\IdeaProjects\untitled\target\classes edu.sdccd.cisc191.ReadResourceFileDemo
Alex,Smith,99,A
Jolene,Schmidt,100,A
Mackinzie,Jensen,86,B
Julie,Brown,100,A

Process finished with exit code 0

问题

这意味着程序第一次跳过了追加,或者跳过了追加但由于某种原因没有显示在文件中。

当我打开文件时 TestResult.csv 它只有前 3 行。

但是,手动添加的第 4 行作为 Julie,Brown,100,A 没有出现。

非常感谢您的帮助!

尝试在 filewriter 上调用 flush 方法。

在第一个运行中,可能是缓冲区没有刷新到文件中。通常,写入文件后调用 flush 是一个好习惯。

你需要冲洗你的作家:

try (FileWriter fw=new FileWriter(file, true)) {
    fw.append("\nJulie,Brown,100,A");
    fw.flush();
}
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println(content);

发生了什么事

当您打开并写入 第一次 时,它被写入 缓冲区 。 此缓冲区在 try-with 块 内维护。但是缓冲区还没有被刷新。它通过显式调用 flush() or by closing the IO-stream/writer which is done implicitly by close():

来刷新

Closes the stream, flushing it first.

try 块以右大括号 } 结束时,

close 会自动隐式调用。这种 try-with block 的资源节约态度是 auto-closable 概念的好处。接口 AutoCloseable 由大多数 IO 流实现,例如 FileWriter.

由于您的 independent 读操作 Files.readAllBytes(file.toPath()) 也在这个 try-with 块中,它从文件中读取在磁盘上,而不是来自缓冲区。

如何修复

理论上从 fw 的缓冲区读取是合乎逻辑的,但这并不容易实现。

但是您可以使用 fw.flush() 刷新 try-with 块 内的缓冲区,然后读取。此刷新将缓冲区写入磁盘,因此您可以从磁盘读取并期望刷新的内容显示为已读。

或者您可以在 try-with 块 之后移动读取操作,以确保之前已刷新和写入缓冲区。

中建议了这两个修正 - 有点过时但有效。