2

次の例を検討してください。

FILE* stream = fopen("my_file", "w");
fputs("hello", stream);

fputs() の実行中に電源が失われるとどうなりますか?

その後、サイズがゼロではなく、最初のバイトが「h」ではない「my_file」を見つけることができますか? はいの場合、ゼロであることが保証されていますか、それとも任意の値を含むことができますか?

もちろん、誰も私たちのファイルに触れていないと仮定してください。

編集: また、ターゲット ディスク ドライブ/デバイスが、内部にバッファリングされたすべてのデータを書き込むのに十分な時間電力を維持できるタイプであると仮定します。

POSIXはこれについて何か言いたいことがありますか? Linuxは?Windows はありますか?

編集: STDIO ストリーム API の実装方法の詳細に焦点を当てるつもりはありませんでした。POSIXを仮定すると、これが私が本当に意味することです:

int fd = open("my_file", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
write(fd, "hello", 5);

編集: POSIX はサイズをファイルのメタ データと見なすため、質問はおそらく次のように言い換えることができます: 上記のコードの結果として、ファイル データとそのファイルのメタ データを別々の段階でディスクにコミットすることはできますか?

編集: http://www.sqlite.org/atomiccommit.htmlでこれを見つけました:

7.5 安全な追加セマンティクスを持つファイルシステム

SQLite バージョン 3.5.0 で導入された別の最適化では、基になるディスクの「安全な追加」動作を利用します。SQLite は、データがファイル (具体的にはロールバック ジャーナル) に追加されると、最初にファイルのサイズが増加し、次にコンテンツが書き込まれると想定していることを思い出してください。そのため、ファイル サイズが大きくなった後、コンテンツが書き込まれる前に電源が失われた場合、ファイルには無効な「ガベージ」データが含まれたままになります。ただし、VFS の xDeviceCharacteristics メソッドは、ファイルシステムが「安全な追加」セマンティクスを実装していることを示している場合があります。これは、ファイル サイズが大きくなる前にコンテンツが書き込まれることを意味し、停電やシステム クラッシュによってロールバック ジャーナルにゴミが入り込むことはありません。

これは、少なくとも部分的な答えを提供するようです。

4

2 に答える 2

1

に関してはlinux、バッファに書き込んだ内容がすぐにディスクに書き込まれるとは限りません。

をにkernelコピーdatabuffer、後でバックグラウンドで、カーネルはすべてを収集し、dirty buffersそれらを最適にソートして、に書き込みますdisk。これは、と呼ばれwritebackます。これにより、書き込み呼び出しが非常に速く発生し、ほぼ即座に戻ります。また、カーネルがdefer writesよりidle periods多くのバッチを実行できるようにしますwrites together

于 2013-01-21T17:02:43.010 に答える
0

ext3これは、使用中のファイル システム ( 、ext4、 、....) とそれに指定されたマウント時のオプションに大きく依存するxfsため、簡単な万能の答えはありません。おそらく、私たちにあなたの/etc/fstabファイルシステムを見せて、知りたいファイルシステムを教えていただければ、より良い答えが得られるかもしれません...

于 2013-01-21T17:35:25.577 に答える