C# 字节[stream.length]-内存不足异常,最佳解决方法?

C# 字节[stream.length]-内存不足异常,最佳解决方法?,c#,stream,binaryreader,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

我试图从文件中读取字节流。然而,当我尝试读取字节时,我得到一个

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

很简单。然而,解决这个问题的最好办法是什么?一次绕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();
}
BinaryReader br=新的BinaryReader(流fs);
//长度约为600000000
长长度=fs.长度;
//这里出错
字节=新字节[长度];
for(int i=0;i

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

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


希望这对您有所帮助

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

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


希望这对你有帮助。首先想象一个大小为2GB的文件。您的代码将分配2GB内存。只需读取文件中您真正需要的部分,而不是一次读取整个文件。 第二:不要这样做:

for (int i = 0; i < Length; i++)
{
   bytes [i] = br.ReadByte();
}
for(int i=0;i
效率很低。要读取流的原始字节,您应该使用如下内容:

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++)
    {
        //...
    }
}
使用(var stream=File.OpenRead(文件名))
{
int bytesToRead=1234;
byte[]buffer=新字节[bytesToRead];
int read=stream.read(buffer,0,buffer.Length);
//对读取的数据执行某些操作…例如:
for(int i=0;i
很好。首先想象一个大小为2GB的文件。您的代码将分配2GB内存。只需读取文件中您真正需要的部分,而不是一次读取整个文件。 第二:不要这样做:

for (int i = 0; i < Length; i++)
{
   bytes [i] = br.ReadByte();
}
for(int i=0;i
效率很低。要读取流的原始字节,您应该使用如下内容:

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++)
    {
        //...
    }
}
使用(var stream=File.OpenRead(文件名))
{
int bytesToRead=1234;
byte[]buffer=新字节[bytesToRead];
int read=stream.read(buffer,0,buffer.Length);
//对读取的数据执行某些操作…例如:
for(int i=0;i
我相信流对象的实例化已经读取了文件(到缓存中)。然后循环将内存中的字节复制到另一个数组


那么,为什么不使用数据到“br”中,而不是进行进一步的复制呢?

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


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

您真的需要将所有数据都存储在内存中吗?用例是什么?在32位进程中分配600兆字节的几率很低。很难在地址空间中找到这么大的洞,除非您在启动程序后立即这样做。当然有更好的解决办法,你不会给我们机会去猜的。您需要一个64位操作系统或使用内存映射文件。这很简单:您已经用完了可以在.net中寻址的内存(2GB)。也许,您不应该尝试在
bytes=newbyte[Length]中分配600M行。您想对这些数据做什么?这是一条调试器消息。这并不意味着您的代码内存不足。问题是如何使用此数组?您真的需要阵列吗?您真的需要将所有数据都存储在内存中吗?用例是什么?在32位进程中分配600兆字节的几率很低。很难在地址空间中找到这么大的洞,除非您在启动程序后立即这样做。当然有更好的解决办法,你不会给我们机会去猜的。您需要一个64位操作系统或使用内存映射文件。这很简单:您已经用完了可以在.net中寻址的内存(2GB)。也许,您不应该尝试在
bytes=newbyte[Length]中分配600M行。您想对这些数据做什么?这是一条调试器消息。这并不意味着您的代码内存不足。问题是如何使用此数组?你真的需要数组吗?BinaryReader不会将所有数据加载到内存中,它会在需要时加载小块数据。BinaryReader不会将所有数据加载到内存中,它会在需要时加载小块数据。这是一种非常优雅的方式,谢谢。我正在尝试传回一个byte[]数组,以便将其存储在数据库中(以便在以后读取该项)。是否可以使用上述代码执行此操作?好的。我不确定在数据库中存储如此大的数据块是否是一个好主意。但是如果你真的想这样做,你必须分割数据。读取文件的一部分