简体   繁体   English

PrintWriter:读取和写入同一文件 - 文件在再次打开之前似乎不会保存

[英]PrintWriter: reading and writing to the same file - file appears not to be saved before being opened again

I am trying to create a program which will write new data to a save file. 我正在尝试创建一个程序,将新数据写入保存文件。 The file has three "slots", that is, three Strings separated by delimiters. 该文件有三个“槽”,即由分隔符分隔的三个字符串。 The main program calls the saver program with the slot as an argument, and the saver program opens the file, reads the existing String in each slot to local variables, replaces the one corresponding to the given slot with a new String, and overwrites the file with the new slots. 主程序以slot作为参数调用saver程序,saver程序打开文件,将每个槽中的现有String读取到局部变量,用新String替换与给定槽对应的String,并覆盖文件与新的插槽。 This should result in only the given slot being updated, and the other two remaining the same as before. 这应该导致只更新给定的槽,而其他两个保持与以前相同。

The main program calls the saver three times in a row, once for each slot. 主程序连续三次调用保护程序,每个插槽一次。 This SHOULD result in the save file looking as follows (where # is the delimiter): 这应该导致保存文件看起来如下(其中#是分隔符):

Before first call: #EMPTY#EMPTY#EMPTY 在第一次通话之前:#EMPTY#EMPTY#EMPTY

After first call: #NewString#EMPTY#EMPTY 第一次调用后:#NewString#EMPTY#EMPTY

After second call: #NewString#NewString#EMPTY 第二次调用后:#NewString #NewString#EMPTY

After third call: #NewString#NewString#NewString 第三次调用之后:#NewString #NewString #NewString

.

Instead of this, what happens is: 而不是这样,会发生什么:

Before first call: #EMPTY#EMPTY#EMPTY 在第一次通话之前:#EMPTY#EMPTY#EMPTY

After first call: #NewString#EMPTY#EMPTY 第一次调用后:#NewString#EMPTY#EMPTY

After second call: #EMPTY#NewString#EMPTY 第二次调用后:#EMPTY #NewString#EMPTY

After third call: #EMPTY#EMPTY#NewString 第三次调用后:#EMPTY#EMPTY #NewString

The printwriter (PrintWriter saver = new PrintWriter(new FileWriter(fileName))) gets opened in the saver file, not the main file, so a new PrintWriter gets opened for each call. 打印机(PrintWriter saver = new PrintWriter(new FileWriter(fileName)))在保护程序文件中打开,而不是在主文件中打开,因此每次调用都会打开一个新的PrintWriter。 I .flush() and .close() at the end of the saver method (it's a void method). 我在保护程序方法结束时使用.flush()和.close()(这是一个void方法)。

Why does it seem like the file doesn't get saved before the next call to the method happens? 为什么在下一次调用方法之前,文件似乎没有被保存? =S Do I have to impose some kind of wait-until-file-isn't-open-anymore command, and it so, how do I do that? = S我是否必须施加某种wait-until-file-not-open-anymore命令,这样,我该怎么做?

public static void main(String[] args) throws IOException {

        SaveGame.saveState("adventure/save/s1.save", new Adventure(), 0);

        SaveGame.saveState("adventure/save/s2.save", new Adventure(), 1);

        SaveGame.saveState("adventure/save/s3.save", new Adventure(), 2);
        }

And then: 然后:

public class SaveGame {

public static void saveState(String fileName, Adventure a, int slot) throws IOException {   

    //UPDATE MASTER SAVE FILE save.txt
    String[] save = new String[3]; 

    try {
        Scanner openSave = new Scanner(new FileReader("/adventure/save/save.txt"));
        openSave.useDelimiter("#");
        save[0] = openSave.next();
        save[1] = openSave.next();
        save[2] = openSave.next();
        openSave.close();
    }
    catch (FileNotFoundException e) {
        save[0] = "EMPTY";
        save[1] = "EMPTY";
        save[2] = "EMPTY";
    }

    save[slot] = "newString"; //change the CURRENT save in the given slot to the new

    PrintWriter updater = new PrintWriter(new FileWriter("adventure/save/save.txt"));
    updater.println("#" + save[0] + "#" + save[1] + "#" + save[2]);
    updater.flush();
    updater.close();

The reader reads the file /adventure/save/save.txt , whereas the writer writes to adventure/save/save.txt . 读者读取文件/adventure/save/save.txt ,而编写者写入adventure/save/save.txt Unless you run the program from the root of your file system ( / ), these are not the same files. 除非您从文件系统的根目录( / )运行程序,否则它们不是相同的文件。

Apply the DRY principle (Don't Repeat Yourself). 应用DRY原则(不要重复自己)。 Create a constant containing the file path, and use the constant everywhere you're using the path. 创建一个包含文件路径的常量,并在使用路径的任何地方使用常量。 That will avoid such bugs. 这将避免这样的错误。

Also, close the reader and the writer in a finally block, or use the Java 7 try-with-resources construct. 另外,在finally块中关闭reader和writer,或者使用Java 7 try-with-resources构造。

It's doing exactly what you tell it to. 这正是你告诉它的。 Each time you call saveState, you set a single index of a newly instantiated array to "newString", and display the array. 每次调用saveState时,都会将新实例化数组的单个索引设置为“newString”,并显示该数组。

Edit 编辑

Sorry, I misread your code. 对不起,我误读了你的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM