fprintf や fwrite などの関数を呼び出しても、すぐにデータがディスクに書き込まれるわけではなく、しきい値に達するまでデータがバッファリングされることがわかっています。私の質問は、fseek 関数を呼び出した場合、新しい位置にシークする前に、これらのバッファリングされたデータがディスクに書き込まれるかどうかです。それとも、データがまだバッファにあり、新しい位置に書き込まれていますか?
チェン
はい; fseek()
実行した操作に応じて、ファイルが本来あるべきように見えることを保証しますfwrite()
。
C 標準、ISO/IEC 9899:1999 §7.19.9.2fseek()
は次のように述べています。
fseek 関数は、stream が指すストリームのファイル位置標識を設定します。読み取りエラーまたは書き込みエラーが発生した場合、ストリームのエラー インジケータが設定され、fseek は失敗します。
バッファーがフラッシュされることが保証されているかどうかはわかりませんが、十分に近い位置を探している場合はそうでない可能性があります。ただし、バッファリングされたデータが新しい位置に書き込まれる方法はありません。バッファリングは単なる最適化であるため、透過的でなければなりません。
データをフラッシュする必要があると指定されているとは思いませんfseek
が、データが実際にディスクに書き込まれるときは、書き込み関数が呼び出されたときにストリームがあった位置に書き込まれる必要があります。データがまだバッファリングされている場合でも、後続のシークがあったとしても、フラッシュされたときにそのバッファをファイルの別の部分に書き込むことはできません。
あなたの本当の懸念は、fseek
.
いいえ、そうはなりません。期待どおりに動作します。
fflush
以前
にあなたが呼び出した要件について漠然とした記憶がありますがfseek
、確認できる C 標準のコピーが手元にありません。(そうしないと、未定義の動作または実装定義、またはそのようなものになります。) 一般的な Unix 標準では、次のように指定されています。
特定のストリームに対する ftell() 以外の最新の操作が fflush() である場合、基礎となるオープン ファイル記述のファイル オフセットは、fseek() によって指定された位置を反映するように調整されます。
[...]
ストリームが書き込み可能で、バッファリングされたデータが基になるファイルに書き込まれていない場合、fseek() は、書き込まれていないデータをファイルに書き込み、ファイルの st_ctime および st_mtime フィールドを更新用にマークします。
ただし、これは ISO C 標準の拡張としてマークされているため、Unix プラットフォーム (または同様の保証を行う他のプラットフォーム) 以外では当てにできません。