从一个流中下载文件并将其保存到另一个流中的zip,而不将所有数据都放在内存中

时间:2018-02-08 20:15:22

标签: c# .net azure

我是处理流或类似事件的完全初学者,所以如果你看到任何明显错误的话......那就是原因。我有一些文件存储在天蓝色。我需要拿起文件,拉上它们,然后退回拉链。

我用1GB文件测试了这个,虽然它可以工作,但它最终使用了2.5GB的内存。最后一行开始和完成之间的内存使用量激增。我不确定为什么这会把所有内容加载到内存中,所以我不太清楚我应该做些什么来防止这种情况发生。这样做的正确方法是什么?我唯一能想到的就是在某个地方指定缓冲区大小,但在我看到的任何地方都可能有一个小的默认值。

FileStream zipToOpen = new FileStream("test.zip", FileMode.Create);
ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Update, true);
ZipArchiveEntry zipEntry = archive.CreateEntry("entryName", CompressionLevel.Optimal);

// ... some azure code
file = await dir.GetFileReference(fileName);
fileContents = await file.OpenReadAsync().ConfigureAwait(false);

await fileContents.CopyToAsync(zipEntry.Open()).ConfigureAwait(false);

1 个答案:

答案 0 :(得分:2)

只需将档案创建为

即可
ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create);

您的内存消耗将降至最低(在我的测试用例中,它从900M降至36M)......

似乎问题与 ZipArchiveMode.Update

有关
void Zip(IEnumerable<string> files, Stream inputStream)
{
    using (var zip = new System.IO.Compression.ZipArchive(inputStream, System.IO.Compression.ZipArchiveMode.Create))
    {
        foreach (var file in files.Select(f => new FileInfo(f)))
        {
            var entry = zip.CreateEntry(file.Name, System.IO.Compression.CompressionLevel.Fastest);
            using (var s = entry.Open())
            {
                using (var f = File.Open(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    f.CopyTo(s);
                }
            }
        }
    }
}