【问题标题】:Loading saved byte array to memory stream causes out of memory exception将保存的字节数组加载到内存流导致内存不足异常
【发布时间】:2014-03-28 09:37:41
【问题描述】:

在我的程序中,用户选择了一个位图作为 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);
}

流的长度相同。我不明白一个人如何抛出内存不足异常而另一个没有。如何加载此位图?

附:我也试过了

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

【问题讨论】:

  • 通常 GDI+(Image 的构建基础)会通过 Out Of Memory 执行,而实际上发生的情况是您因未处理一次性对象而导致 Out Of Handles。
  • 您的this.Panel.BackgroundImage = Image.FromStream(stream); 代码多久调用一次?
  • 此时它只被调用一次。我想它只会被调用几次。

标签: c# image bitmap out-of-memory memorystream


【解决方案1】:

你可以看看这个库。

http://arraysegments.codeplex.com/

项目描述

ArraySegment 的轻量级扩展方法,对字节数组特别有用。

支持 .NET 4.0(客户端和完整版本)、.NET 4.5、Metro/WinRT、Silverlight 4 和 5、Windows Phone 7 和 7.5、所有可移植库配置文件和 XBox。

【讨论】:

    【解决方案2】:

    我认为问题出在这里:

    myDataRow.BackgroundImageByteArray = stream.ToArray();
    

    Stream.ToArray() 。请注意,这会将流转换为长度 = stream.Length 的字节数组。 Stream.Legnth 是流缓冲区的大小,它将大于加载到其中的实际数据。您可以通过在while 循环中使用Stream.ReadByte() 来解决此问题,直到它返回-1,表示流中的数据结束。

    【讨论】:

    • 谢谢,缓冲区比它包含的数据大是有道理的。我得到了循环的东西,但是我很难找到如何创建一个可变字节数组,我可以在 while 循环中一次添加一个字节。任何指针? (没有双关语)
    猜你喜欢
    • 1970-01-01
    • 2014-06-07
    • 2012-02-03
    • 2012-12-15
    • 1970-01-01
    • 2011-05-26
    • 2013-06-22
    • 2013-12-09
    • 2011-09-02
    相关资源
    最近更新 更多