2012-08-03 166 views
0

背景:可以Stream.CopyTo(流)損壞的數據?

我有一個旨在完成一個簡單的任務以下WriteFileToStream功能:從文件中獲取數據,並將其複製到流。

我原來使用Stream.CopyTo(Stream)方法。但是,經過長時間的調試過程後,我發現這是導致我的處理管道中出現「損壞的數據」錯誤的原因。

梗概:

使用Stream.CopyTo(流)方法產生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); 
    //} 
} 
+2

從看着你混合起來的代碼 - *你*的代碼是越野車,並在上面寫上多餘的數據到'目的地,而'CopyTo()'實際上工作正常。 – Lucero 2012-08-03 16:55:57

+1

致智者:作爲開發者,這總是我們的錯。它(幾乎)從來不是操作系統或框架中的錯誤。 – 2012-08-03 16:58:22

+0

當您使用MSDN示例時,您的控制檯輸出如何:http://msdn.microsoft.com/en-us/library/dd782932.aspx – CrashCodes 2012-08-03 18:23:28

回答

8

看看這段代碼:

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

這破開始。您忽略Stream.Read的結果。 從來沒有這樣做。假設文件在取長度和從中讀取文件之間被截斷 - 你會寫一堆零。假設不管是什麼原因,Read調用並不會讀取整個數據(儘管不存在本地文件,但如果通過網絡訪問的文件可能會顯示該行爲,我不會感到驚訝) - 再次,您我會錯誤地寫出一堆零。

話雖如此,這當然是一個奇怪的情況。就個人而言,我總是試圖將流視爲流 - 我不喜歡根據該值進行大小和預分配。例如,如果文件在閱讀時增長,則代碼可以很好地證明這個問題。不知道更多細節,我不知道這是否可能。

但是不,Stream.CopyTo罰款,據我所知。我認爲這個問題更可能在別處。

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

你能夠可靠地重現問題嗎?一個簡短但完整的程序展示問題將更有可能說服我在框架中的錯誤:)

+0

Jon:爲什麼我需要關閉在存在'使用'語句? – JTech 2012-08-03 17:22:01

+0

@JTech:目前還不清楚你指的是我的答案。但是,如果「Read」調用引發異常,那麼您當前的代碼將留下一個打開的流。 – 2012-08-03 17:34:47

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

long fileLength = outputStream.Length; //這會導致'fileLength'爲0 - 這本身就是一個錯誤。 – JTech 2014-01-13 20:33:30