Tim Bray の記事"Saving Data Safely"は未解決の問題を残しました。今日、それは 1 か月以上経ちましたが、フォローアップが見られなかったので、ここでトピックを扱うことにしました。
この記事のポイントの 1 つは、FileOutputStream を使用する場合、安全のために FileDescriptor.sync() を呼び出す必要があることです。Java を 12 年間やっている間、Java コードが同期しているのを見たことがなかったので、最初はとてもイライラしました。特に、ファイルへの対処はかなり基本的なことです。また、FileOutputStream の標準 JavaDoc は、同期をほのめかしませんでした (Java 1.0 - 6)。いくつかの調査の結果、ext4 が実際に同期を必要とする最初のメインストリーム ファイル システムである可能性があることがわかりました。(明示的な同期が推奨される他のファイル システムはありますか?)
この件についての一般的な考えに感謝しますが、具体的な質問もいくつかあります。
- Android はいつファイル システムと同期しますか? これは定期的であり、さらにライフ サイクル イベントに基づいている場合もあります (たとえば、アプリのプロセスがバックグラウンドに移行するなど)。
- FileDescriptor.sync() はメタデータの同期を処理しますか? つまり、変更されたファイルのディレクトリを同期しています。FileChannel.force() と比較してください。
- 通常、FileOutputStream に直接書き込むことはありません。これが私の解決策です(同意しますか?):
FileOutputStream fileOut = ctx.openFileOutput(file, Context.MODE_PRIVATE); BufferedOutputStream out = new BufferedOutputStream(fileOut); try { out.write(something); out.flush(); fileOut.getFD().sync(); } finally { out.close(); }