【问题标题】:Byte[stream.length] - out of memory exception, best way to solve?Byte[stream.length] - 内存不足异常,最好的解决方法是什么?
【发布时间】:2014-06-10 13:13:07
【问题描述】:

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

由于内存不足,函数评估被禁用 异常

很简单。但是,解决此问题的最佳方法是什么?一次循环长度是 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();
}

谢谢

【问题讨论】:

  • 你真的需要所有内存中的数据吗?用例是什么?
  • 在 32 位进程中分配 600 兆字节的几率非常低。很难在地址空间中找到一个 大的漏洞,除非您在启动程序后立即 这样做。当然有一个更好的解决方案,你不给我们一个猜测的机会。您需要 64 位操作系统或使用内存映射文件。
  • 这很简单:您已经用完了可以在 .net 中解决的内存 (2GB)。或许,您不应该尝试在bytes = new byte[Length]; 行中分配600M。你想用这些数据做什么?
  • 这是一条调试器消息。这并不意味着您的代码内存不足。
  • 问题是如何使用这个数组?你真的需要一个数组吗?

标签: c# stream binaryreader


【解决方案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++)
    {
        //...
    }
}

【讨论】:

  • 一种非常优雅的方式,谢谢。我正在尝试传回一个 byte[] 数组,以便可以将其存储在数据库中(以便在以后读取该项目)是否可以使用上面的代码来执行此操作?
  • 好吧。我不确定在数据库中存储如此大的数据块是否是个好主意。但如果你真的想这样做,你必须拆分数据。读取文件的一部分,提交到数据库,读取下一部分并再次提交。
  • 是的,我认为这可能是答案。很遗憾你不能附加字节,但感谢代码!
【解决方案2】:

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

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

希望有帮助

【讨论】:

    【解决方案3】:

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

    那么,为什么不将数据用于“br”而不是进一步复制呢?

    【讨论】:

    • BinaryReader 不会将所有内容加载到内存中,它通过在需要时加载小块数据来工作。
    猜你喜欢
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 2015-09-01
    • 1970-01-01
    • 2012-05-11
    • 2019-08-10
    • 1970-01-01
    相关资源
    最近更新 更多