2014-02-25 20 views
2

在我的程序中的某個位置,用戶選擇一個位圖用作Panel對象的背景圖像。當用戶這樣做時,程序立即用背景圖像繪製面板,一切正常。當用戶單擊「保存」時,以下代碼將位圖保存到DataTable對象。將保存的字節數組加載到內存流會導致內存不足異常

MyDataSet.MyDataTableRow myDataRow = MyDataSet.MyDataTableRow.NewMyDataTableRow(); //has a byte[] column named BackgroundImageByteArray 
using (MemoryStream stream = new MemoryStream()) 
{ 
    this.Panel.BackgroundImage.Save(stream, ImageFormat.Bmp); 
    myDataRow.BackgroundImageByteArray = stream.ToArray(); 
} 

一切工作正常,這個流沒有內存不足的異常,即使它包含所有的圖像字節。但是,當應用程序啓動並加載保存的數據時,以下代碼將引發「內存不足」異常:

using (MemoryStream stream = new MemoryStream(myDataRow.BackGroundImageByteArray)) 
{ 
    this.Panel.BackgroundImage = Image.FromStream(stream); 
} 

流的長度相同。我不明白如何拋出一個內存不足的例外,而另一個不會。我怎樣才能加載這個位圖?

P.S.我也試着

using (MemoryStream stream = new MemoryStream(myDataRow.BackgroundImageByteArray.Length)) 
{ 
    stream.Write(myDataRow.BackgroundImageByteArray, 0, myDataRow.BackgroundImageByteArray.Length); //throw OoM exception here. 
} 
+0

通常GDI +(構建什麼'Image')將會通過Out Of Memory執行,當真正發生了什麼事情時,您會由於不配置一次性對象而導致無法處理。 –

+0

你的'this.Panel.BackgroundImage = Image.FromStream(stream);'調用的代碼多久? –

+0

此時它只被調用一次。我想它永遠不會被稱爲超過少數幾次。 – user2320861

回答

0

我認爲這個問題是在這裏:

myDataRow.BackgroundImageByteArray = stream.ToArray(); 

Stream.ToArray()。請注意,這會將流轉換爲length = stream.Length的字節數組。 Stream.Legnth是流的緩衝區的大小,它將大於加載到其中的實際數據。您可以通過在while循環中使用Stream.ReadByte()來解決此問題,直到它返回-1,表示數據流內的數據結束。

+0

謝謝,這是有道理的,緩衝區將比它包含的數據更大。我得到循環的東西,但我無法找到如何創建一個可以在while循環中一次添加一個字節的可變字節數組。任何指針? (沒有雙關語意) – user2320861

0

你可能會給這個圖書館一看。

http://arraysegments.codeplex.com/

項目描述

輕型擴展方法用於ArraySegment,對於字節數組特別有用。

支持.NET 4.0(客戶端和完整版),.NET 4.5,Metro/WinRT,Silverlight 4和5,Windows Phone 7和7.5,所有便攜式庫配置文件和XBox。