6

アプリケーションの特定のポイントでファイルが書き込まれた後、ディスクへの同期を強制しようとしています。Linux上で動作するので、実行するだけで逃げることができました

Runtime.getRuntime().exec("sync");

ただし、Linux固有のシステムコールを導入するのではなく、

java.io.FileDescriptor#sync();

ただし、私はApache VFSを使用してローカルファイルシステムで操作を実行しており、私の知る限り、基になるファイル記述子へのアクセスは提供されていません。しかし、同期を強制するために書き込まれたばかりの実際のファイル記述子にアクセスする必要がありますか?たとえば、FileDescriptorを使用して同じ効果の同期を呼び出すことはできませんか?

FileDescriptor.in.sync();

それは有効なアプローチであり、結果はLinuxでsyncを呼び出す場合の結果と一致しますか?

VFSで基盤となるFileDescriptorにアクセスできるかどうか、またはどのようにアクセスできるかを誰かが知っている場合に備えて、知っておくと便利です。

編集:それは

FileDescriptor.in.sync();

Linuxでは動作しません(ただし、Eclipseから実行するとWindowsマシンで動作します)。

new FileOutputStream(new File("anyfile")).getFD().sync();

間違いなく機能し、これを呼び出した結果は、Linuxsyncコマンドを直接呼び出した結果と一致します。ただし、冗長ファイル出力ストリームを開いたり閉じたりする必要があるため、必ずしも理想的ではありません。それはうまくいくように見えるので、これが悪い考えかもしれない他の理由はありますか?同期に使用できるFileDescriptorを取得する他の方法はありますか?

4

1 に答える 1

4

私は少し前にそのような問題を調査します:質問1質問2

Linuxでは、java.io.FileDescriptor#sync呼び出しにより、記述子に関連付けられたファイルの変更されたデータがディスクに送信されます。(その安価なディスクは書き込みをスキップする傾向があり、データを信頼性の低い(別名NVRAMなし)書き込みキャッシュに配置するだけです。これは別の/追加の問題です。)他のファイルの変更されたデータも書き戻されることを保証するものではありません。これは、syncまたは基礎となるfsyncPOSIX関数の契約ではありません。

ただし、特定の状況(たとえば、data = orderedモードのext3)では、ファイルのfsyncがファイルシステムの変更されたデータをバックアップします。他のアプリケーションが大量のダーティブロックを作成したという理由だけで、これによりかなりの遅延が発生する可能性があるため、これは本当に楽しいことです。

于 2013-03-07T16:37:09.557 に答える