0

的背景:

我有以下 WriteFileToStream 函数,旨在完成一项简单的工作:从文件中获取数据并将其复制到 Stream。

我最初使用的是 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即使数据存在,调用也不会读取整个数据(对于本地文件不太可能,但如果通过网络访问的文件可能表现出这种行为,我不会感到惊讶) - 再次,你' d 错误地写了一堆零。

话虽如此,这肯定是一个奇怪的情况。就我个人而言,我总是尝试将流视为流- 我不喜欢根据该值获取大小和预分配。例如,如果文件在您阅读时增长,您的代码可以很好地证明该问题。在不知道更多细节的情况下,我不知道这是否可能。

但不,Stream.CopyTo据我所知很好。我认为问题更可能出在其他地方。

请注意,在您注释掉的版本中,您不会关闭输出流 - 而在显式读取文件的版本中(不使用using语句,顺便说一句......)您会这样做。

你能可靠地重现问题吗?一个简短但完整的程序来演示这个问题将更有可能说服我框架中的一个错误:)

于 2012-08-03T16:52:37.947 回答
0

我已经评论了我认为你的错误在哪里。

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

    //your code here should work when you fix the bug
}

这就是你想要的:

long fileLength = outputStream.Length;

outputStream.Write(bytes, 0, bytes.Length);
于 2013-12-30T20:39:41.737 回答