读取二进制文件时避免LOH

读取二进制文件时避免LOH

本文介绍了读取二进制文件时避免LOH的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题是对
的跟进

我最初问为什么使用 File.ReadAllBytes 导致快速内存使用,并且使用该方法得出结论将数据放在大对象堆上,这在运行时期间无法轻易回收。

I originally asked why using File.ReadAllBytes was causing rapid memory use and it was concluded using that method put the data on the large object heap which cannot be easily reclaimed during run-time.

我现在的问题是如何避免这种情况?

My question now is how to avoid that situation?

using (var fs = new FileStream(path, FileMode.Open))
{
    using (var ms = new MemoryStream())
    {
        byte[] buffer = new byte[2048];
        int bytesRead;
        while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, bytesRead);
        }
        return new CustomFile { FileValue = ms.ToArray() };
   }
}

以下代码旨在解决此问题以块的形式读取文件而不是一次读取所有文件但似乎有同样的问题。

The following code was intended to get around the problem by reading a file in chunks instead of all at once but it seems to have the same problem.

推荐答案

内存流保存内部整个数据的数组(最后返回)。只要你保持连接到内存流,你读取2048字节的块是没关系的。如果你需要将数据作为包含整个文件的数组返回,那么你最终会经常创建大型对象堆的数组。

The memory stream holds an internal array fo the whole data (which you return in the end). It doesn't matter that you read in chunks of 2048 bytes as long as you keep concatenating to the memory stream. If you need to return the data as an array containing the entire file, then you will end up often creating that array the large object heap.

如果目的地(BLOB)字段或类似的)不允许您以单字节数组之外的任何其他方式传入数据,然后您无法绕过分配包含所有数据的字节数组。

If the destination (a BLOB field or similar) does not allow you to pass in the data in any other way than a single byte array, then you can't get around allocating a byte array that holds all the data.

将数据传输到目标的最佳方法当然是目标也支持流语义。

The best way of transferring data to the destination is of course if the destination also supports a stream semantic.

int Transfer(Stream source, Stream target)
{
   byte buffer = new byte[BufSize];
   int totalBytesTransferred = 0;
   while ((bytesRead = source.Read(buffer, 0, BufSize)) > 0)
   {
      target.Write(buffer, 0, bytesRead);
      totalBytesTransferred += bytesRead;
   }
   return totalBytesTransferred;
}

如果可能,取决于目标(例如数据库BLOB)是否支持是否打开目标流。

If this is possible depends on whether the target (Database BLOB for example) supports opening a stream to the target or not.

这篇关于读取二进制文件时避免LOH的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 03:14