的背景:
我有以下WriteFileToStream函数,用于完成一个简单的工作:从文件中获取数据并将其复制到Stream.
我最初使用的是Stream.CopyTo(Stream)方法.但是,经过漫长的调试过程后,我发现这是导致我的处理管道中出现"损坏数据"错误的原因.
概要:
使用Stream.CopyTo(Stream)方法产生65536个字节的数据,并且流不能正确处理.
使用Stream.Write(...)方法可以生成45450个字节的数据,并且流正确处理.
问题:
任何人都可以看到为什么以下使用CopyTo可能导致无关数据被写入流?
请注意:WriteFileToStream中的最终代码取自对此问题的回答:将MemoryStream保存并加载到文件中
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);
//}
}
Run Code Online (Sandbox Code Playgroud)
看看这段代码:
byte[] bytes = new byte[fileLength];
file.Read(bytes, 0, (int)fileLength);
Run Code Online (Sandbox Code Playgroud)
那是开始的.你忽略了结果Stream.Read.永远不要那样做.假设文件在获取长度和读取之间被截断 - 你将写出一堆零.假设无论出于何种原因,Read调用都不会读取整个数据,即使它在那里(不太可能是本地文件,但如果通过网络访问的文件可能表现出这种行为,我也不会感到惊讶) - 再次,你' d错误地写了一堆零.
话虽如此,这肯定是一个奇怪的情况.我个人总是试图将流视为流 - 我不喜欢采用大小并根据该值预先分配.例如,如果文件在您阅读时生长,您的代码可以很好地证明该问题.在不知道更多细节的情况下,我不知道这是否可行.
但不,Stream.CopyTo就我所知,这很好.我认为这个问题更容易出现在其他地方.
请注意,在注释掉的版本中,您不会关闭输出流 - 而在显式读取文件的版本中(不使用using语句,顺便说一句......),您可以这样做.
您能够可靠地重现问题吗?一个简短但完整的程序演示问题将更有可能说服我框架中的错误:)