1. ホーム
  2. c#

[解決済み] あるストリームの内容を別のストリームにコピーするにはどうすればよいですか?

2022-03-18 08:35:16

質問

あるストリームの内容を別のストリームにコピーするのに最適な方法は何ですか?このための標準的なユーティリティ・メソッドはありますか?

どのように解決するのですか?

.NET 4.5 以降は Stream.CopyToAsync メソッド

input.CopyToAsync(output);

これは Task というように、完了すると続きができるようになります。

await input.CopyToAsync(output)

// Code from here on will be run in a continuation.

を呼び出す場所によっては CopyToAsync が作られると、それに続くコードはそれを呼び出したのと同じスレッドで継続されるかもしれませんし、そうでないかもしれません。

は、その SynchronizationContext を呼び出したときにキャプチャされた await は、継続がどのスレッドで実行されるかを決定します。

さらに、この呼び出しは (これは実装の詳細であり、変更される可能性があります) リードとライトのシーケンスを行います (I/O完了時にブロックするスレッドを無駄にしないだけです)。

.NET 4.0以降では、.NET 4.0に対応した Stream.CopyTo メソッド

input.CopyTo(output);

.NET 3.5以前の場合

フレームワークにはこれを支援するものが組み込まれていないので、このように手動でコンテンツをコピーする必要があります。

public static void CopyStream(Stream input, Stream output)
{
    byte[] buffer = new byte[32768];
    int read;
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
    {
        output.Write (buffer, 0, read);
    }
}

注1:このメソッドでは、進捗状況を報告することができます(これまで読んだバイト数はx個 ...)
注2:なぜ固定バッファサイズを使用し input.Length ? なぜなら、その長さは利用できないかもしれないからです! からの ドキュメント :

Stream から派生したクラスがシークをサポートしていない場合、Length、SetLength、Position、および Seek を呼び出すと NotSupportedException がスローされます。