15

I /Oに関するcplusplus.comチュートリアルを読んでいました。最後に、fstreamバッファがディスク上のファイルと同期されていることを示しています

明示的に、マニピュレータを使用する場合:特定のマニピュレータがストリームで使用されると、明示的な同期が行われます。これらのマニピュレータは、flushとendlです。

明示的に、メンバー関数sync()を使用する場合:パラメーターを受け取らないストリームのメンバー関数sync()を呼び出すと、即時同期が発生します。この関数は、ストリームに関連するバッファーがない場合、または障害が発生した場合に、-1に等しいint値を返します。それ以外の場合(ストリームバッファが正常に同期された場合)、0を返します。

他のいくつかの暗黙のケース(destroyやstream.close()など)に加えて

fstream :: flush()とfstream :: sync()の呼び出しの違いは何ですか?endl?

私のコードでは、常にflush()を使用しています。

std :: flush()に関するドキュメント:

ストリームバッファをフラッシュする

ストリームに関連付けられたバッファを、制御された出力シーケンスに同期します。これは事実上、バッファ内のすべての未書き込み文字が、制御された出力シーケンスにできるだけ早く書き込まれる(「フラッシュされる」)ことを意味します。

std :: streambuf :: sync()に関するドキュメント:

入力バッファを文字のソースと同期します

ストリームバッファを制御されたシーケンス(ファイルストリームの場合のファイルのように)と同期するために呼び出されます。パブリックメンバー関数pubsyncは、この保護されたメンバー関数を呼び出して、このアクションを実行します。

これが初心者の質問である場合は、私を許してください。私は初心者です。

4

4 に答える 4

15

basic_ostream :: flush これは、コミットされていない変更を基になるバッファーに書き込む非仮想関数です。エラーが発生した場合は、使用するストリームオブジェクトにエラーフラグを設定します。これは、連鎖を可能にするために、戻り値がストリーム自体への参照であるためです。

basic_filebuf :: sync これは、保留中のすべての変更を基になるファイルに書き込み、成功または失敗を通知するエラーコードを返す仮想関数です。

endl これをに適用すると、ストリームostreamに書き込みが行われ、そのストリーム'\n'が呼び出さflushれます。

つまり、本質的に:flushは任意のストリームのより一般的な関数ですsyncが、ファイルに明示的にバインドされています。flushは非仮想ですが、syncは仮想です。これにより、継承の場合に(基本クラスへの)ポインターを介してそれらを使用する方法が変更されます。さらに、エラーの報告方法も異なります。

于 2013-01-10T06:35:59.783 に答える
6

syncinputストリームのメンバーであり、未読の文字はすべてバッファから削除されます。flushoutputストリームのメンバーであり、バッファリングされた出力はカーネルに渡されます。

于 2013-01-10T06:27:15.303 に答える
4

C ++ I / Oには、streambufferlocalelocale ::facet -sなどの多くのクラス間の連携が含まれます。

特にsync、とはとの両方にflush存在するメンバー関数であるため、それらは異なることを行うため、参照しているドキュメントに注意してください。streamstreambuf

オンストリーム は、コンテンツを宛先にフラッシュflushするようにバッファに指示するようにストリームに指示します(リダイレクションに注意してください) 。これにより、「保留中の書き込み」が残らないようになります。

std::endl、で適用したthestream場合<<

thestream.put('\n'); thestream.flush();

常にストリーム上、コンテンツをフラッシュし(出力用)、可能な限り読み取り(入力用)してバッファーを補充するようにバッファーに指示するようにストリームsync指示します。

-in buffersoverflow --syncは、「バッファフル」(出力の場合)および「バッファエンプティ」(入力の場合)の状況を処理するために、によって内部的に呼び出すこともできることに注意してください。

したがって、私は、ストリームとバッファプログラムsync(仮想であり、さまざまなバッファタイプでオーバーライドされる)をバッファリングするためにストリームで使用される「内部」関数でありflush、ストリームとクライアントプログラム間のインターフェイスであると感じています。

endl...は単なるショートカットです。

于 2013-01-10T07:26:39.857 に答える
1

私はそれが次のようであると理解しました:

flush()ライブラリバッファからOSの書き込みバッファにデータを取得し、最終的に完全な同期(データは完全に書き出される)になりますが、同期が完了するのは間違いなくOS次第です。

sync()特定のOSで可能な範囲で、完全な同期を強制的に実行しようとしますが、関係するOSはこれを容易にする場合とそうでない場合があります。

つまりflush()、データをバッファから取り出して、書き込む行に並べます。
sync()可能であれば、今すぐデータを確実に書き出すようにします。

それが私の理解でしたが、考えてみると、どうやってこの理解に至ったのか思い出せないので、他の人からも聞いてみたいです。

于 2013-01-10T06:24:59.177 に答える