2011-01-26 26 views
41

可能性の重複:
Do I need to manually close a ifstream?std :: fstreamを閉じる必要がありますか?

私はfstream.close()を呼び出す必要があるかfstreamは破壊にストリームを閉じ、適切なRAIIオブジェクトですか?

メソッド内にローカルstd::ofstreamオブジェクトがあります。クローズしないでこのメソッドを終了した後にファイルが常に閉じられていると仮定できますか?私はデストラクタのドキュメントを見つけることができませんでした。

+0

はい重複しています。ありがとうございました。私はそれを見つけられませんでした。 –

+3

正確な重複はありません。参照される質問はifstreamsに固有であり、これは一般的にfstreamに関するものです。 –

答えて

65

私はこれまでの回答は誤解を招くものだと思います。

fstreamはスコープの終わりに近い自動的を行い、適切なRAIIオブジェクトで、スコープの終わりに十分なされて閉じたときに、手動でcloseを呼び出すための全く絶対に必要はありません。

特に、「ベストプラクティス」ではないため、出力をフラッシュする必要はありません。

Drakoshaがそうである間に、closeはストリームの失敗ビットをチェックする可能性がありますが、とにかく誰もそれを行いません。

理想的な世界では、stream.exception(ios::failbit)を事前に呼び出して、fstreamのデストラクタでスローされた例外を処理するだけです。しかし、残念なことに、デストラクタの例外はC++の壊れた概念なので、それは良い考えではありません。

したがってファイルを閉じるのが成功したかどうかを確認する場合は、手動で行う必要がありますが、それだけです。

+4

私は実際にデータがディスクにコミットされていることを確認する必要があるアプリケーションで作業しているので、毎回結果が近いことを確認します。また、少し外れても、** closeは(少なくともLinuxでは)flush **を保証するものではなく、デストラクタがフラッシュしないかどうかはわかりません。私は実際にそれをフラッシュして閉じ、両方のエラーをチェックする "ベストプラクティス"と言います。 – Drakosha

+7

@Drakosha:データがディスクに完全にフラッシュされることを保証するには、 'flush'または' close'が保証するものとはまったく異なっています。あなたが一般的に考えることができる最高のものは、プロセスの中からOSレベルにデータを「フラッシュ」することです。プロセスを強制終了しても、データが書き込まれるのを妨げることはありません。 C++標準には、ファイルシステムの一部として提示される他のストレージとは対照的に、永続ストレージという概念がないため、永続ストレージにデータが確実にコミットされるように移植可能なAPIはありません。 –

+1

私はまた、そのLinuxの動作に少し驚いています。 fstreamデストラクタは 'close'メンバ関数を呼び出す必要があり、' close'は '' fclose' 'のように閉じるために必要で、 'fclose'はストリームをフラッシュするように定義されています。したがって、デストラクタは確実にフラッシュしなければなりませんが、プラグがマシンに引っ張られる危険がある場合、フラッシングは必ずしもあなたが望むことを行うとは限りません。そのためには(非標準のC++) 'fsync'が必要です。 –

1

私はエイミー・リーの答えに追加するには

+5

fstreamがRAIIオブジェクトの場合、それは閉じられ、バッファはとにかくフラッシュされます。主な問題は、すべての制御フローでエラー処理が必要かどうかです。 –

+4

申し訳ありませんが、何とか+2だったので-1です。手動でリソースを解放することは、プログラミングの悪い兆候か、コンテナの目的の誤解のいずれかです。 – GManNickG

+0

@GMan:私はあなたのファイルが適切に閉じられたかどうかは気にしないことが例外的なケースであると主張します。ほとんどの状況で自分でclose()を呼び出す必要があります。 *あまりにも多くのソフトウェア開発者は、私がむしろユーザーファイルシステムの信頼性と可用性については考えていないと仮定しています。 –

6

を言われてきたもの、それはこのようので、それを手動で行う方が良いでしょうことを、あなたはバッファをフラッシュする必要が原因、それはあなたのfstreamを閉じるために良い習慣だと思いますエラーもチェックできます。 "close" manpageに応じところで

、:

が 近い(の戻り値をチェックしない)は共通だが、それにもかかわらず 深刻なプログラミングエラーです。前の write(2)操作のエラーが最初に最後のclose()で と報告されている可能性がかなりあるのは、 です。ファイルを閉じるときに の戻り値をチェックしないと、 がデータを黙って失う可能性があります。これは特にNFSでは 、ディスククォータでは になります。カーネルが 書き込みを延期するよう

成功したクローズは、データが正常に ディスクに保存されていることを を保証するものではありません。 ストリームが閉じているときに、ファイルシステムがバッファをフラッシュするのは一般的ではありません。 が必要な場合は、データが物理的に に格納されていることを確認してください。fsync(2)を使用してください。 (現時点では がディスクハードウェアに依存します。)

+1

手動で行うほうがよい*エラーをチェックする必要がある場合は、必ず手動で閉じるべきではありません。あなたは例外的な事例から一般的な練習をすることはできません。一般的なケースでは、終了するときに、成功した方法は気にしないので、自動的に行かせてください。 – GManNickG

+3

@GMan:エラーをチェックしていない場合、データがディスクにないと誤​​っていることになります。 – Drakosha

+1

@Drakisha:しかし、スティーブは言ったように、一度閉じると(自動的に行われます)、エラーかどうかは私の手にはありません。また、あなたの "拡張"は非標準のC++です。ここでは、標準的な 'fstream' C++について言及しています。 – GManNickG

関連する問題