1

Windows が Linux と比較してファイルを処理する方法を理解するのに少し苦労しています。「データベース」として使用しているファイルのエントリを削除しようとしています (これは単なる通常のファイルです)。Java は残念ながらこれを行う方法を提供していないため、削除したいエントリを除くすべてのエントリを一時ファイルにコピーし、古いデータベースを削除し、新しい空のデータベース ファイルを作成し、一時ファイルの内容を新しいデータベース ファイルを作成し、一時ファイルを削除して終了します。

私の関数のコードは次のとおりです。

private void removeSelectedItem(String entryToRemove) {

    //original database file
    File database = new File("catalog");

    //all entries except selected will be written here first
    File temp = new File("temp");

    boolean endOfFileFlag = false;
    String line = "";

    try {

        //used for reading original database file
        BufferedReader databaseReader =
            new BufferedReader(new FileReader(database));

        //used for writing to newly-created temp file
        BufferedWriter tempWriter =
            new BufferedWriter(new FileWriter(temp, true));

        /*
         * Read original database line by line and test to see if the line
         * has the course prefix and id. If it does, it won't be written to
         * the temp file.
         */
        while (endOfFileFlag == false) {

            line = databaseReader.readLine();

            /*
             * This code is ugly. If possible, this check needs to be
             * made in the conditions of the while loop.
             */
            if (line == null) {

                endOfFileFlag = true;
                break;

            }

            //tests to see if the line is to be removed
            if ( !line.contains(entryToRemove))
                tempWriter.write(line + "\r\n");

        }

        endOfFileFlag = false; //reset this for the next loop
        databaseReader.close(); //database will be deleted
        tempWriter.close(); //temp file is written
        database.delete(); //delete this to create a new updated one below

        database.createNewFile();

        //writes to the new database
        BufferedWriter databaseWriter =
                new BufferedWriter(new FileWriter(database, true));

        //reads from the temp file
        BufferedReader tempReader =
            new BufferedReader(new FileReader(temp));

        //read temp line by line and add each line to a new catalog file
        while (endOfFileFlag == false) {

            line = tempReader.readLine();

            /*
             * This code is ugly. If possible, this check needs to be made
             * in the conditions of the while loop. Attempts thus far have
             */
            if(line == null){

                endOfFileFlag = true;
                break;

            }

            databaseWriter.write(line + "\r\n");

        }

        tempReader.close(); //temp will be deleted
        databaseWriter.close(); //new database has been written
        temp.delete(); //temp file no longer needed

        setUpInfo(); //update the lists with the new catalog info

    }catch(IOException e){

        System.out.println("removeSelectedItem()");
        e.printStackTrace();

    }

}

このコード (Linux では "\n" のみである "\r\n" を除く) は Linux で完全に実行されますが、Windows では、エントリを削除するためにイベント ハンドラーをアクティブにすると、プログラムが余分なエントリを追加するだけです。デバッグ後、 への呼び出しdatabase.delete()は実際にはデータベース ファイルを削除していませんが、 への呼び出しtemp.delete()は一時ファイルを削除していることがわかりました (本来のように)。これは奇妙だと思ったので、ファイルのアクセス許可を確認したところ、「読み取り/書き込み」に設定されています。インターネットで見つけた次の修正を試しました。

endOfFileFlag = false; //reset this for the next loop
databaseReader.close(); //database will be deleted
tempWriter.close(); //temp file is written
database.delete(); //delete this to create a new updated one below
//new code
database = null;
System.gc();

しかし、うまくいきませんでした。他に起こりうることは何も考えられません。

4

2 に答える 2