9

基になるストリームが である StreamWriter がありFileStreamます。FileStream次のコードは、がそのバッファをファイル システム上の実際のファイルにもフラッシュすることを保証しますか? または、 を明示的に呼び出す必要がFlush()ありFileStreamますか?

using (var fs = new FileStream("blabla", FileMode.Append)) {
    using (var sw = new StreamWriter(fs)) {
        sw.WriteLine("Hello, I want to be flushed.");
        sw.Flush(); //I need this to also flush onto the file, not just to the FileStream
    }
}

MSDNによると、「ストリームをフラッシュしても、明示的に Flush または Close を呼び出さない限り、その基になるエンコーダーはフラッシュされません」が、FileStream を「基になるエンコーダー」と見なすことができるかどうかはわかりません。

また、FileOptions.WriteThrough を指定しない場合、2 つのストリームが閉じられる前にプログラムがクラッシュした場合でも、OS が最終的にフラッシュされた行をディスクに書き込むことが保証されますか (たとえば、using {}ブロックがなく、Flush())?

私のシナリオでは、(ロギングのために) ストリームを開いたままにしておく必要があるため、using {}ブロックを使用できませんが、プログラムがクラッシュした場合でもデータが常にディスクに書き込まれるようにしたいと考えています。電源がシャットダウンされ、OS がディスクにフラッシュされていない場合は、データを失う余裕がありClose()ます。

4

2 に答える 2

9

Flushはい、 onを呼び出すStreamWriterと、基になるストリームがFlushed になります。4.5 バージョンは、次で終わるプライベートFlush(bool,bool)関数を呼び出します。

if (flushStream)
{
    this.stream.Flush();
}

flushStreamは最初のパラメータ、はが構築されthis.streamたストリーム、StreamWriterの呼び出しはFlush()ですFlush(true,true)


(回答の古い部分 - 私は回答において非常に遠回しでした。回答の最も関連性の高い部分を一番上に移動しました)

私が見つけることができるドキュメントでは明示的に綴られていませんが、別のストリームを渡すことによって構築されたストリームクラスは、そのストリームの「所有権を取得する」と想定する必要があります (特に明記されていない限り)。

つまり、StreamWriterusing を構築しfsたら、自分自身に対して直接的なアクションを実行するべきではありませんfs


MSDN から引用した部分は、後の文に関連しています。

これにより、エンコーダーはその状態 (部分的な文字) を保持できるため、次の文字ブロックを正しくエンコードできます。このシナリオは、エンコーダーが隣接する文字を受信した後にのみ特定の文字をエンコードできる UTF8 および UTF7 に影響します。

つまりWrite、完全な文字ではなく、いくつかの Unicode サロゲートを指定して にデータを渡した可能性があります。Flushこれらのサロゲートをストリームに書き込みません。整形式の (完全な) 文字列を常に に渡している限り、Writeこれについて心配する必要はありません。


于 2012-10-24T06:15:14.273 に答える
4

ブロックを使用して使用すると、ストリームの破棄が保証されます!

ストリームのチェーンでは、最も外側のストリーム (チェーンの先頭) をi.e StreamWriter in your case閉じると、すべてが閉じます。i.e FileStream

Flush メソッドは、強制的に内部バッファーをすぐに書き込みます。Flush は、ストリームがclosedのときに自動的に呼び出されるため、次のことを行う必要はありません。

s.Flush();s.Close();

そのため、最上位のストリームが閉じられるとすぐに、そのストリームがフラッシュされてから、コンテンツをフラッシュする下位のストリームが閉じられます。

たとえば、このチェーンを考えてみましょう

FileStream->GZipStream->StreamWriter

だから、StreamWriterを閉じた瞬間

StreamWriterフラッシュして閉じます。また、根底に閉じますGZipStream

GzipStreamフラッシュして閉じます。基になるものも閉じますFileStream

ファイルストリームflushescloses

于 2012-10-24T06:04:27.487 に答える