加载大内存压缩文件时出现内存错误ASP.NET C#

v1uwarro  于 2023-11-20  发布在  .NET
关注(0)|答案(1)|浏览(138)

我正在使用MemoryStream,但当文件内存过大且内存不足时会出错。控制器如何下载大于500MB的大型zip文件?因为我的文件已经800MB。请帮助我解决控制器中的问题。

[HttpGet(ZipFileMinhChung)]
[ProducesResponseType(typeof(VoidMethodResult), (int)HttpStatusCode.BadRequest)]
public async Task<IActionResult> ZipFileMinhChungAsync([FromQuery] BaoCaoDanhMucMinhChungRequestViewModel request)
{
    var result = await _reportQueries.ExportZipFileMinhChungAsync(request).ConfigureAwait(false);

    var zipName = $"FilesMinhChung-{DateTime.Now.ToString("yyyy_MM_dd_HHmmss")}.zip";
    using (MemoryStream ms = new MemoryStream())
    {
        using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
        {
            foreach (var item in result)
            {
                using (HttpClient client = new HttpClient())
                {
                    var mediaUrl = _configuration["Gateway"] + item.FilePath;
                    // Download the file content from the external link
                    Stream fileContent = await client.GetStreamAsync(mediaUrl);

                    // Create a temporary file to store the file content
                    string tempFilePath = Path.GetTempFileName();

                    // Write the file content to the temporary file
                    using (FileStream fileStream = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write))
                    {
                        await fileContent.CopyToAsync(fileStream);
                    }

                    // Copy stream file to zip
                    archive.CreateEntryFromFile(tempFilePath, "TieuChi" + item.MaTieuChuanTieuChi + "/" + item.MaMinhChung + "/" + item.FileName);
                }
            }
        }
        ms.Position = 0;
        return File(ms.ToArray(), "application/zip", zipName);
    }
}```

字符串

gpnt7bae

gpnt7bae1#

C#对于大于2Gb的字节数组有一个问题。内存流将使用数组进行存储,它将过度分配以确保它有足够的空间。
绝对最简单的解决方案是在分配内存流时指定容量。将其设置为int.MaxValue应该可以避免小于2Gb的问题。
下一个最简单的解决方案可能是为zip存档使用文件流:

// Create a temporary file to store the file content
string tempFilePath = Path.GetTempFileName();
using var fs = File.Create(tempFilePath);
using (var archive = new ZipArchive(fs, ZipArchiveMode.Create, true))
{
...
}
fs.Position = 0;
return File(fs, "application/zip", zipName);

字符串
请注意,您可以,也可能应该,将数据直接复制到zip存档条目:

var entry = archive.CreateEntry("TieuChi" + item.MaTieuChuanTieuChi + "/" + item.MaMinhChung + "/" + item.FileName);
using var entryStream = entry.Open();
await fileContent.CopyToAsync(entryStream );


请注意,您可能需要某种方法来清理临时文件,但我不确定推荐的方法是什么。另一种方法是创建自己的内存流,使用多个字节数组存储数据。

相关问题