4

新しいデータを保存ファイルに書き込むプログラムを作成しようとしています。ファイルには 3 つの「スロット」、つまり区切り記号で区切られた 3 つの文字列があります。メインプログラムはスロットを引数としてセーバープログラムを呼び出し、セーバープログラムはファイルを開き、各スロットの既存の文字列をローカル変数に読み取り、指定されたスロットに対応するものを新しい文字列に置き換え、ファイルを上書きします新しいスロットで。これにより、特定のスロットのみが更新され、他の 2 つは以前と同じままになります。

メイン プログラムは、スロットごとに 1 回ずつ、連続して 3 回セーバーを呼び出します。これにより、保存ファイルは次のようになります (# は区切り文字です)。

最初の呼び出しの前: #EMPTY#EMPTY#EMPTY

最初の呼び出しの後: #NewString#EMPTY#EMPTY

2 回目の呼び出し後: #NewString#NewString#EMPTY

3 回目の呼び出し後: #NewString#NewString#NewString

.

これの代わりに、次のことが起こります。

最初の呼び出しの前: #EMPTY#EMPTY#EMPTY

最初の呼び出しの後: #NewString#EMPTY#EMPTY

2 回目の呼び出し後: #EMPTY#NewString#EMPTY

3 回目の呼び出し後: #EMPTY#EMPTY#NewString

printwriter (PrintWriter saver = new PrintWriter(new FileWriter(fileName))) は、メイン ファイルではなくセーバー ファイルで開かれるため、呼び出しごとに新しい PrintWriter が開かれます。saver メソッドの最後に .flush() と .close() を追加します (これは void メソッドです)。

メソッドへの次の呼び出しが発生する前にファイルが保存されないように見えるのはなぜですか? =S なんらかのファイルが開かれないまで待機するコマンドを課す必要がありますか?

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);
        }

その後:

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();
4

2 に答える 2

3

リーダーはファイルを読み取り/adventure/save/save.txt、ライターはファイルに書き込みますadventure/save/save.txt。ファイル システムのルート ( ) からプログラムを実行しない限り/、これらは同じファイルではありません。

DRY の原則を適用します (Don't Repeat Yourself)。ファイル パスを含む定数を作成し、パスを使用しているすべての場所でその定数を使用します。それはそのようなバグを回避します。

また、finally ブロックでリーダーとライターを閉じるか、Java 7 の try-with-resources コンストラクトを使用します。

于 2012-12-25T17:32:53.020 に答える
0

それはあなたが言ったことを正確にやっています。saveState を呼び出すたびに、新しくインスタンス化された配列の単一のインデックスを「newString」に設定し、配列を表示します。

編集

申し訳ありませんが、コードを読み間違えました。

于 2012-12-25T17:41:47.837 に答える