5

私は sc2replay 解析ツールに取り組んでいます。MPQLIB http://code.google.com/p/mpqlib/の上に構築します

残念ながら、このツールはファイルチャネルを使用して bzip ファイルを読み取り、map(MapMode.READ_ONLY, hashtablePosition, hashTableSize);

その関数を呼び出した後、ファイル チャネルを閉じても、その過程でファイルは解放されません。具体的には、ファイルの名前を変更/移動することはできません。

この問題は Java 7 で発生し、Java 6 では問題なく動作します。

これを複製するための簡単なコード スニペットを次に示します。

    FileInputStream f = new FileInputStream("test.SC2Replay");
    FileChannel fc = f.getChannel();

    fc.map(MapMode.READ_ONLY, 0,1);

    fc.close();

    new File("test.SC2Replay").renameTo(new File("test1.SC2Replay"));

fc.map をコメントアウトすると、ファイルの名前を変更できます。

PS ここからFileChannel を閉じる必要がありますか?

ファイルチャネルとファイルストリームの両方を閉じる必要はないと述べています。これは、一方を閉じると他方が閉じられるためです。また、どちらかまたは両方を閉じようとしましたが、それでも機能しませんでした。

Java 7 で FileChannel.map を使用してデータを読み取った後にファイルの名前を変更する方法はありますか?

4

3 に答える 3

2

良い一日、

FileChannel.map が Java 7 で問題を引き起こしているようです。FileChannel.map を使用すると、ファイルを閉じることができなくなります。

FileChannel.map(MapMode.READ_ONLY, position, length) を使用する代わりに、簡単な回避策があります。

あなたが使用することができます

ByteBuffer b = ByteBuffer.allocate(length); 
fc.read(b,position);
b.rewind();
于 2012-10-25T11:19:18.487 に答える
0

これは文書化されたバグです。バグ レポートは Java 1.4 に言及しており、ドキュメントのバグと見なされています。ファイル チャネルを閉じても、基になるストリームは閉じられません。

于 2012-10-25T09:38:36.980 に答える
0

Sun JRE を使用している場合は、その実装にキャストし、それ自体を解放するように指示することでごまかすことができます。ファイルが閉じられていることに依存していない場合、または別の JRE を使用する予定がない場合にのみ、これを行うことをお勧めします。

ある時点で、このようなものが適切なパブリック API になることを願っています。

try (FileInputStream stream = new FileInputStream("test.SC2Replay");
     FileChannel channel = stream.getChannel()) {

    MappedByteBuffer mappedBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, 1);
    try {
        // do stuff with it
    } finally {
        if (mappedBuffer instanceof DirectBuffer) {
            ((DirectBuffer) mappedBuffer).cleaner().clean();
        }
    }
}
于 2015-08-18T01:47:20.257 に答える