简体   繁体   中英

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. 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

After first call: #NewString#EMPTY#EMPTY

After second call: #NewString#NewString#EMPTY

After third call: #NewString#NewString#NewString

.

Instead of this, what happens is:

Before first call: #EMPTY#EMPTY#EMPTY

After first call: #NewString#EMPTY#EMPTY

After second call: #EMPTY#NewString#EMPTY

After third call: #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. I .flush() and .close() at the end of the saver method (it's a void method).

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?

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 . 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). 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.

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.

Edit

Sorry, I misread your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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