在 .net Core 中使用 HttpClient 下载分块编码文件

Posted

技术标签:

【中文标题】在 .net Core 中使用 HttpClient 下载分块编码文件【英文标题】:Download chunked encoded file using HttpClient in .net Core 【发布时间】:2018-07-26 17:55:48 【问题描述】:

我正在使用 API 使用 HttpClient 下载文件。当我的整个文件适合单个请求时,我可以保存文件并正确打开它。

当整个文件不适合我的最大块大小时,我必须向我的 API 发出多个请求以获取文件,并且它会以分块编码返回。猜测是这些块没有正确解码并最终在我的文件中损坏它。

有没有办法对来自 GetStreamAsync 的响应进行分块解码?

public byte[] GetFileContent(File file)

    var baseFileUri = BASE_URI + $"platform/files/file.Id";

    int chunkSize = 128 * 1024;

    chunkSize = file.NativeSize <= chunkSize ? file.NativeSize : chunkSize;
    int start = 0;

    using (MemoryStream stream = new MemoryStream())
    
        while (start < file.NativeSize)
        
            Get(baseFileUri, new List<KeyValuePair<string, string>>()  new KeyValuePair<string, string>("offset", start.ToString()), new KeyValuePair<string, string>("size", chunkSize.ToString()) , stream);

            start = start + chunkSize;

            if (file.NativeSize < start + chunkSize)
            
                chunkSize = file.NativeSize - start;
            
        

        return stream.ToArray();
    


private void Get(string uri, List<KeyValuePair<string, string>> parameters, Stream stream)

    var requestUri = BuildUriString(uri, parameters);

    var methodResult = _client.GetStreamAsync(requestUri);
    methodResult.Result.CopyTo(stream);

【问题讨论】:

Stream.CopyTo 已经进行了分块(默认大小为 81920 referencesource.microsoft.com/#mscorlib/system/io/…)。 【参考方案1】:

在您的代码中,您通过执行多个请求手动获取块。当请求的 API 支持分块响应时,您可能会尝试设置 "Transfer-Encoding": "chunked" 标头并让 HttpClient 库处理分块响应。可以在 HttpClient 上设置标头,如下所示:

_client.DefaultRequestHeaders.TransferEncodingChunked = false;

【讨论】:

需要检查API是否支持。

以上是关于在 .net Core 中使用 HttpClient 下载分块编码文件的主要内容,如果未能解决你的问题,请参考以下文章

HttpClien高并发请求连接池 - PoolingHttpClientConnectionManager

如何将此 .NET RestSharp 代码转换为 Microsoft.Net.Http HttpClient 代码?

.net core系列之《.net core中使用MySql以及Dapper》

ASP.NET Core中的缓存[1]:如何在一个ASP.NET Core应用中使用缓存

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用AutoMapper进行实体映射

使用eclipse阅读java源码