0

背景:

簡単なジョブを完了するための次の WriteFileToStream 関数があります。ファイルからデータを取得し、ストリームにコピーします。

私はもともと Stream.CopyTo(Stream) メソッドを使用していました。しかし、長いデバッグ プロセスの後、これが処理パイプラインのさらに先にある「破損したデータ」エラーの原因であることがわかりました。

あらすじ:

Stream.CopyTo(Stream) メソッドを使用すると、65536 バイトのデータが生成され、ストリームが正しく処理されません。

Stream.Write(...) メソッドを使用すると、45450 バイトのデータが生成され、ストリームが正しく処理されます。

質問:

CopyTo を次のように使用すると、無関係なデータがストリームに書き込まれる可能性がある理由を誰でも理解できますか?

注意してください: WriteFileToStream の最終的なコードは、この質問への回答から取られたものです: Save and load MemoryStream to/from a file

public static void WriteFileToStream(string fileName, Stream outputStream)
{
    FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    long fileLength = file.Length;
    byte[] bytes = new byte[fileLength];
    file.Read(bytes, 0, (int)fileLength);
    outputStream.Write(bytes, 0, (int)fileLength);
    file.Close();
    outputStream.Close();

    // This was corrupting the data - adding superflous bytes to the result...somehow.
    //using (FileStream file = File.OpenRead(fileName))
    //{
    //    // 
    //    file.CopyTo(outputStream);
    //}
}
4

2 に答える 2

8

このコードを見てください:

byte[] bytes = new byte[fileLength];
file.Read(bytes, 0, (int)fileLength);

それはそもそも壊れています。の結果を無視していますStream.Read絶対にしないでください。長さの取得と読み取りの間にファイルが切り捨てられたとします。一連のゼロを書き込みます。何らかの理由でRead、データがそこにあるにもかかわらず、呼び出しがデータ全体を読み取らないとします (ローカル ファイルの場合はありそうにありませんが、ネットワーク経由でアクセスされたファイルがその動作を示しても驚かないでしょう) - 繰り返しますが、あなたは'一連のゼロを間違って書いている可能性があります。

そうは言っても、これは確かに奇妙な状況です。個人的には、常にストリームをストリームとして扱うようにしています。サイズを取得して、その値に基づいて事前に割り当てるのは好きではありません。たとえば、ファイルを読んでいる間にファイルが大きくなった場合、コードはその問題を非常によく示している可能性があります。詳細を知らなければ、それが可能かどうかはわかりません。

しかし、いいえ、Stream.CopyTo私が知る限り大丈夫です。問題は他の場所にある可能性がはるかに高いと思います。

コメントアウトされたバージョンでは、出力ストリームを閉じないことに注意してください-ファイルを明示的に読み取るバージョン(usingステートメントを使用せずに、btw ...)では閉じます。

問題を確実に再現できますか? 問題を示す短いが完全なプログラムは、フレームワークのバグを私に納得させる可能性がはるかに高いでしょう:)

于 2012-08-03T16:52:37.947 に答える