C# for循环C内存不足异常#

C# for循环C内存不足异常#,c#,visual-studio-2010,exception,C#,Visual Studio 2010,Exception,我正在读一个二进制文件。如果我读了一个文件,我的代码工作正常。但当我读取文件夹中的文件时,我得到了一个错误,粘贴在下面。我将添加一些用于读取文件的代码。我正在读取字节数组中的文件: byte[] b = File.ReadAllBytes(args); 以及在阵列中存储数据(指示代码): 如果我只读取一个文件,虽然速度很慢(大小约为40MB),但它仍然可以工作。但当我添加文件夹的路径并再次读取时,我得到了错误 List<ReadRawFiles> list = new List&l

我正在读一个二进制文件。如果我读了一个文件,我的代码工作正常。但当我读取文件夹中的文件时,我得到了一个错误,粘贴在下面。我将添加一些用于读取文件的代码。我正在读取字节数组中的文件:

byte[] b = File.ReadAllBytes(args);
以及在阵列中存储数据(指示代码):

如果我只读取一个文件,虽然速度很慢(大小约为40MB),但它仍然可以工作。但当我添加文件夹的路径并再次读取时,我得到了错误

List<ReadRawFiles> list = new List<ReadRawFiles>();
ReadRawFiles rawFiles;
foreach (var f in sFiles)
                    {
                      rawFiles = new ReadRawFiles(f.File,true,true);
                      list.Add(rawFiles);

                       //rawFiles=null; //clear??
                    }

我认为这是因为:

while (true)
{
    rawData1.Add((double)(BitConverter.ToUInt32(b, curPos) & fff[i]));
    i++;
}

您没有终止条件,它将永远持续,并通过递增
i
并将数据添加到
rawData
ArrayList来继续消耗资源

这里有一些效率很低的部件;一个将整个文件加载到内存中,另一个将不清晰的
fff
数组加载到内存中。
ArrayList
double
保存三分之一(这涉及到将每个
double
装箱,这里非常糟糕)

我强烈建议尝试简化和流化数据,例如:

byte[] buffer = new byte[4];
List<double> rawData = new List<double>();
foreach(var path in paths)
{
    using(var file = File.OpenRead(path))
    {
        while(TryRead(file, buffer, 4))
        {
            const uint MASK = 4095;
            var val = BitConverter.ToUInt32(buffer, 0) & MASK;
            // note that this line looks really dodgy
            rawData.Add((double)val);
        }
    }
}
byte[]buffer=新字节[4];
List rawData=新列表();
foreach(路径中的变量路径)
{
使用(var file=file.OpenRead(path))
{
while(TryRead(文件、缓冲区、4))
{
常数掩码=4095;
var val=BitConverter.ToUInt32(缓冲区,0)和掩码;
//请注意,这条线看起来非常狡猾
rawData.Add((双)val);
}
}
}
使用实用程序方法填充整个4字节块(或失败):

静态bool TryRead(流s,字节[]缓冲区,整数字节)
{
int read=s.read(缓冲区,0,字节),偏移量;
如果(读取0&(读取=s.read(缓冲区、偏移量、字节))>0)
{
字节-=读取;
偏移量+=读取;
}
如果(字节!=0)抛出新的EndOfStreamException();
返回true;//成功
}
不过,我必须强调:

  • uint
    -到-
    的双重转换看起来非常不可能;这不是将double读取为二进制的方式
  • 将所有数据存储为
    double
    听起来同样不太可能——我想不出有什么明显的场景会有用

请张贴实际代码。此外,正如异常的名称所示,内存正在耗尽。如果你在内存中存储了一堆大文件,这很正常。文件夹中有多少文件,它们加起来需要多少内存?你到底想在这里做什么?因为将这些文件加载到内存中是一个非常糟糕的主意,我不知道你想要那个巨大的
fff
数组做什么。处理大型二进制文件的诀窍是流式传输数据。那么:你到底想在这里做什么?使用
ArrayList
并不能让你的意图更加清晰(
List
对于一些
t
会更加清晰)你的代码是一团乱麻,让所有答案都是猜测。清理并重试。使用
b=null
rawFiles=null
只需清除对对象的引用,回收内存由CG决定。在
rawFiles
的情况下,
列表中仍然有一个引用
,因此内存无法回收,因为它仍在使用中。OP的代码没有意义(请参阅“指示性代码”),因为它适用于一个文件,假设实际代码中没有无限循环。@ken2k-我看不出条件是如何终止的。对1个文件似乎有效的内容实际上可能不是,即OP看到了所需的输出,但程序仍在消耗不必要的内存-但是没有引发异常。我将每个文件设置为0,并且在得到异常之前读取了2个文件。@DarrenDavies没有退出条件,因为它不是真正的代码
ReadRawFiles
没有参数。代码甚至不会编译。@Naresh-只要用那些函数更新你的问题,它们不会那么长。我正在复制一个matlab代码,这就是它在那里的实现方式。我会试试你说的。非常感谢。我的文件是40 MB,在内存中读取所有文件不是很快吗?一旦处理完就可以清理吗?@Naresh 40 MB仍然相当大。你知道什么比分配40 MB快吗?没有分配40 MB!特别是当您处于32位进程中并且正在销毁大型对象堆时。同样,完全无法解释的98MB
fff
数组也会造成很大的危害。大量的装箱(
ArrayList
)是另一个巨大的问题。由于问题中的代码非常不清楚,我只能提供指针…我是matlab用户,所以我正在实现类似的事情,我不清楚内存使用情况,因为matlab处理大部分内容。我会研究更多细节。这帮了大忙。谢谢如果我禁用存储引用的列表,我可以读取完整的文件夹。
while (true)
{
    rawData1.Add((double)(BitConverter.ToUInt32(b, curPos) & fff[i]));
    i++;
}
byte[] buffer = new byte[4];
List<double> rawData = new List<double>();
foreach(var path in paths)
{
    using(var file = File.OpenRead(path))
    {
        while(TryRead(file, buffer, 4))
        {
            const uint MASK = 4095;
            var val = BitConverter.ToUInt32(buffer, 0) & MASK;
            // note that this line looks really dodgy
            rawData.Add((double)val);
        }
    }
}
static bool TryRead(Stream s, byte[] buffer, int bytes)
{
    int read = s.Read(buffer, 0, bytes), offset;
    if (read <= 0) return false; // no more data

    bytes -= read;
    offset = read;
    while (bytes > 0 && (read = s.Read(buffer, offset, bytes)) > 0)
    {
        bytes -= read;
        offset += read;
    }
    if (bytes != 0) throw new EndOfStreamException();
    return true; // success
}