-->

读二进制文件时避免LOH(Avoiding the LOH when reading a binar

2019-08-19 04:38发布

这个问题是一个跟进有效的方式,许多二进制文件转移到SQL Server数据库

本来我问为什么用File.ReadAllBytes是导致快速的内存使用,它是用这种方法把对大对象堆无法在运行时很容易回收的数据得出的结论。

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

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() };
   }
}

下面的代码的目的是通过在块,而不是所有的阅读文件一下子得到解决此问题,但它似乎有同样的问题。

Answer 1:

内存流保持一个内部数组FO整个数据(你在最后返回)。 不要紧,你在2048个字节的块读取,只要你不断串联到内存流。 如果您需要将数据作为包含整个文件的数组中返回,那么你最终会经常创建数组大对象堆。

如果目标(BLOB字段或类似)不允许你在数据传递以任何其他方式比单一的字节数组,那么你就不能得到解决分配的字节数组保存所有的数据。

将数据传输到目的地的最佳途径当然是如果目标还支持流语义。

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例如)是否支持打开一个流至目标或没有。



文章来源: Avoiding the LOH when reading a binary