簡體   English   中英

Stream.CopyTo(Stream)會損壞數據嗎?

[英]Can Stream.CopyTo(Stream) Corrupt Data?

的背景:

我具有以下WriteFileToStream函數,該函數旨在完成一個簡單的工作:從文件中獲取數據並將其復制到Stream。

我最初使用的是Stream.CopyTo(Stream)方法。 但是,經過漫長的調試過程,我發現這是我的處理管道中進一步出現“數據損壞”錯誤的原因。

概要:

使用Stream.CopyTo(Stream)方法將產生65536字節的數據,並且流無法正確處理。

使用Stream.Write(...)方法可產生45450字節的數據,並且流可以正確處理。

問題:

誰能看到為什么下面的CopyTo用法可能導致多余的數據被寫入流中?

請注意:WriteFileToStream中的最終代碼來自以下問題的答案: 將MemoryStream保存到文件或從文件加載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);
    //}
}

看下面的代碼:

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

首先是壞的。 您將忽略Stream.Read的結果。 絕對不要那樣做。 假設文件在獲取長度和讀取文件之間被截斷-您將寫入一堆零。 假設由於某種原因,即使存在Read調用也不會讀取全部數據(對於本地文件而言不太可能,但是如果通過網絡訪問的文件可以表現出這種行為,我不會感到驚訝)-將錯誤地寫入一堆零。

話雖如此,這肯定是一個奇怪的情況。 我個人總是嘗試將流視為流 -我不喜歡獲取大小並根據該值進行預分配。 例如,如果文件在讀取過程中增長,則代碼可以很好地說明該問題。 不知道更多細節,我不知道是否可能。

但據我所知, Stream.CopyTo很好。 我認為問題很可能出在其他地方。

請注意,在注釋掉的版本中,您不會關閉輸出流-而在顯式讀取文件的版本中(無需使用using語句btw ...),您可以關閉輸出流。

您能夠可靠地重現該問題嗎? 一個簡短但完整的程序來演示該問題,很可能會說服我框架中的錯誤:)

我已經評論了我認為您的錯誤所在的位置。

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM