2013-02-21 41 views
3

在使用.NET CF的Windows CE設備上。我從REST服務的流中收到一個大文件(12MB)。Convert.FromBase64String上的FormatException c#

這個大文件是Base64格式,但它有兩個小細節,用雙引號(")和每N個字符包圍的內容有一個\\n(不換行字符\n,但實際2個文本字符) 。 所以我需要做的是,刪除引號和\\n或用實際的換行符替換它們。並且還從base64格式轉換。

這是我的代碼:

var input = ApplicationContext.restProxy.GetData(); 

using (StreamReader sr = new StreamReader(input)) 
{ 
    StringBuilder sb = new StringBuilder(); 
    char[] buffer = new char[32]; 
    while (sr.Read(buffer, 0, 32) > 0) 
    { 
     var s = new string(buffer); 
     s = s.Replace("\\n", "\n"); 
     s = s.Trim('"'); 
     sb.Append(s); 
    } 

    byte[] fileBytes = Convert.FromBase64String(sb.ToString()); 

} 

但有了這個代碼,我要麼有OutOfMemoryException,或FormatException當我打電話了Convert.FromBase64String

一些輸入數據的格式如下:

"U1FMaXRlIGZvcm1hdCAzAAQAAQEAQCAgAAAABAAAI2oAAAAAAAAAAAAAAAQAAAABAAAAAAAAAAAA\\nAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAC3iGgUAAAABA/sAAAAaSQP7\\nApsA0wDTAAAAAAAAAAAAAAAAAAAAAAAAAAA ... 

我該怎麼辦沒有填補了設備的內存這些操作,或者有什麼不對結果字符串的格式?

+0

你的代碼的一個明顯的失敗模式是Read()調用返回'\\'但還不是n。修復這將增加你用完內存的機率。幾乎沒有什麼方法可以贏得這裏,我想,請給服務負責人發送一封惡意郵件,讓自己感覺更好。 – 2013-02-21 15:16:49

+1

你得到的'FormatException'是因爲最後一個'sr.Read'將返回不完整的緩衝區(少於32字節),但你在'sb.Append(s)'中追加所有32。你應該使用另一個具有'count'參數的'Append'重載。 – torvin 2013-02-22 06:55:37

+0

爲什麼要從TextReader讀取二進制數據? – leppie 2013-02-22 15:52:40

回答

1

如果您寫入緩衝區逐個檢查字符,則可以獲得更好的結果。

此外,由於文件太大,通過將此數據直接寫入輸出文件可能會獲得更好的結果。否則,您試圖將所有這些數據保存在內存中。

直接發送輸出到一個文件可能會讓你繞過這個問題,但我不知道。我從來沒有遇到過,所以我不知道如何測試它。

這裏是可以採取你的問題護理的樣品的方法:

​​3210

雖然Close()不是必需的,我發現它有助於在那裏你可以在垃圾收集之前調用一定的方法很多次的情況下有機會爲你清理東西。最好是安全。

我希望它提供一些用途。

+0

你提出了一個很好的建議。它可以直接寫入文件。但之後,我必須重新打開文件並將完整的內容從base64轉換爲二進制文件。所以這就是爲什麼我正在嘗試預先做到這一點的方法。 – ohvitorino 2013-02-25 08:12:05