在读取二进制时避免LOH
本文关键字:LOH 读取 二进制 | 更新日期: 2023-09-27 18:07:22
这个问题是将许多二进制文件传输到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() };
}
}
下面的代码是为了解决这个问题,通过读取文件块而不是一次读取,但它似乎有同样的问题。
内存流保存整个数据的内部数组(最后返回)。只要你不断地连接到内存流,你读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)是否支持向目标打开流。