Reputation: 39
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();
Upvotes: 4
Views: 2603
Reputation: 12123
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.
Upvotes: 0
Reputation: 691685
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.
Upvotes: 3