【问题标题】:Better way to process large HttpClient response (400mb) to ZipArchive处理对 ZipArchive 的大型 HttpClient 响应 (400mb) 的更好方法
【发布时间】:2022-01-06 10:00:59
【问题描述】:

我会尽量保持简短和准确。

要求:

从第 3 方下载大型 (400mb) xml 响应并以 ZipArchive 的形式存储在磁盘上。

当前解决方案:

using (var memoryStream = new MemoryStream())
{
    using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
    {
        var file = archive.CreateEntry($"{deliveryDate:yyyyMMdd}.xml");
        using(var entryStream = file.Open())
        {
            using (var payload = new MemoryStream())
            {
                using var response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
                response.EnsureSuccessStatusCode();
                await response.Content.CopyToAsync(payload);
                payload.Seek(0, SeekOrigin.Begin);

                await payload.CopyToAsync(entryStream);
            }
        }
    }

    using (var fileStream = new FileStream(Path.Combine(filePath), FileMode.Create, FileAccess.Write, FileShare.None))
    {
        memoryStream.Seek(0, SeekOrigin.Begin);
        await memoryStream.CopyToAsync(fileStream);
    }
}

其他信息:

我可以将一个 400mb 的文件压缩到大约。 20mb 大约 40 秒。 1/4 是下载 3/4 是压缩。 httpClient 被重用。 该代码在一个长期存在的应用程序中运行,该应用程序作为 k8 linux pod 托管。

当前解决方案存在的问题:

我不明白这个实现是否会自行清理。我将感谢您指出潜在的泄漏。

【问题讨论】:

    标签: c# .net memory stream zip


    【解决方案1】:

    可能更直接地写入文件流会更快/更干净 并且应该处理响应:

    using System.IO.Compression;
    
    string url = "https://stackoverflow.com/questions/70605408/better-way-to-process-large-httpclient-response-400mb-to-ziparchive";
    string filePath = "test.zip";
    
    
    using(HttpClient client = new HttpClient())
    using (var fileStream = new FileStream(Path.Combine(filePath), FileMode.Create, FileAccess.Write, FileShare.None))
    using (var archive = new ZipArchive(fileStream, ZipArchiveMode.Create, true))
    {
        var file = archive.CreateEntry($"test.xml");
        using (var entryStream = file.Open())
        using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
        {
           response.EnsureSuccessStatusCode();
           var stream = await response.Content.ReadAsStreamAsync();
           await stream.CopyToAsync(entryStream);       
                
        }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      • 2014-04-14
      • 2013-04-23
      • 1970-01-01
      • 1970-01-01
      • 2014-03-18
      • 2012-10-28
      相关资源
      最近更新 更多