1

一部の Java コードでメモリ マップ ファイルを使用して、2G ファイルにすばやく書き込みます。ファイル全体をメモリにマッピングしています。私のソリューションの問題は、書き込み先のファイルが不思議なことに消えたり、ディスクに何らかのエラーが発生したりした場合、それらのエラーが Java コードに反映されないことです。

実際、Java コードからは、書き込みが正常に完了したように見えます。このタイプの障害をシミュレートするために作成した単体テストを次に示します。

File twoGigFile = new File("big.bin");
RandomAccessFile raf = new RandomAccessFile(twoGigFile, "rw");
raf.setLength(Integer.MAX_VALUE);
raf.seek(30000); // Totally arbitrary
raf.writeInt(42);
raf.writeInt(42);

MappedByteBuffer buf = raf.getChannel().map(MapMode.READ_WRITE, 0, Integer.MAX_VALUE);
buf.force();
buf.position(1000000); // Totally arbitrary
buf.putInt(0);

assertTrue(twoGigFile.delete());

buf.putInt(0);
raf.close();

このコードはエラーなしで実行されます。これは私にとってかなりの問題です。この種の問題について語っているものを見つけることができないようです。メモリマップされたファイルを取得して例外を正しくスローする方法を知っている人はいますか? または、データが実際にファイルに書き込まれることを確認する別の方法がある場合は?

メモリ マップ ファイルよりもはるかに遅いため、RandomAccessFile の使用を避けようとしています。ただし、他に選択肢がない場合もあります。

4

1 に答える 1

2

できません。JavaDoc を引用するには:

マップされたバイト バッファーのすべてまたは一部は、いつでもアクセスできなくなる可能性があります [...] マップされたバイト バッファーのアクセスできない領域にアクセスしようとしても、バッファーの内容は変更されず、指定されていない例外がいずれかの時点でスローされます。アクセスの、または後で。

理由は次のとおりです。マップされたバッファを使用すると、ファイルではなくメモリが変更されます。メモリがたまたまファイルによってバックアップされているという事実は、OS がバッファリングされたブロックをディスクに書き込もうとするまでは関係ありません。これは、OS によって完全に管理されます (つまり、アプリケーションはそれが起こっていることを認識しません)。

ファイルが自分の下に消えることが予想される場合は、別のメカニズムを使用して、これが発生するかどうかを確認する必要があります。1 つの可能性は、時々 を使用してファイルにアクセスし、RandomAccessFileスローされるエラーをキャッチすることです。OS によっては、これでも十分でない場合があります。たとえば、Linux では、開いているハンドルを持つプログラムのファイルが、外部で削除されたとしても存在します。

于 2012-09-26T21:26:59.667 に答える