字节[stream.length] - 内存不足异常,解决的最佳方法是什么?

时间:2014-06-10 13:13:08

标签: c# stream binaryreader

我正在尝试从文件中读取字节流。但是,当我尝试读取字节时,我得到了一个

  

由于内存不足,功能评估被禁用   例外

相当直截了当。但是,解决这个问题的最佳方法是什么?它是否在1028处长度环绕一次?或者有更好的方法吗?

我正在使用的C#

BinaryReader br = new BinaryReader(stream fs);

// The length is around 600000000
long Length = fs.Length;

// Error here
bytes = new byte[Length];

for (int i = 0; i < Length; i++)
{
   bytes [i] = br.ReadByte();
}

由于

3 个答案:

答案 0 :(得分:3)

好。首先。想象一个大小为例如1的文件。 2GB。您的代码将分配2GB的内存。只需一次读取您真正需要的文件部分而不是整个文件。 其次:不要做这样的事情:

for (int i = 0; i < Length; i++)
{
   bytes [i] = br.ReadByte();
}

这是非常低效的。要读取流的原始字节,请执行以下操作:

using(var stream = File.OpenRead(filename))
{
    int bytesToRead = 1234;
    byte[] buffer = new byte[bytesToRead];

    int read = stream.Read(buffer, 0, buffer.Length);

    //do something with the read data ... e.g.:
    for(int i = 0; i < read; i++)
    {
        //...
    }
}

答案 1 :(得分:0)

当您尝试分配数组时,CLR会在操作系统为其提供的虚拟内存中连续放置它。但是,虚拟内存可能会碎片化,因此可能无法使用连续的1 GB块,因此会出现OutOfMemoryException。机器有多少物理RAM并不重要,这个问题不仅限于托管代码(尝试在本机C中分配一个巨大的数组,你会发现类似的结果)。

我建议使用几个较小的数组,一个ArrayList或List,而不是分配一个庞大的数组,这样框架可以按块分配数据。

希望有所帮助

答案 2 :(得分:0)

我相信流对象的实例化已经读取了文件(进入缓存)。然后你的循环将内存中的字节复制到另一个数组。

那么,为什么不将数据用于&#34; br&#34;而不是进一步复制?