【问题标题】:How to read ChunkedEncodingReadStream in .net core如何在 .net 核心中读取 ChunkedEncodingReadStream
【发布时间】:2021-01-22 08:54:15
【问题描述】:

我正在使用 HttpClient 下载文件并尝试以 4MB 的块处理它。客户端将流返回为ChunkedEncodingReadStream。我要下载的文件大小为 50MB。但是,当我尝试使用 ReadAsync 在 4MB 缓冲区中读取它时,我注意到它返回的读取计数仅为 1321 字节。

我的问题是:如何正确读取流?

我的代码:

var client = _httpClientFactory.CreateClient();
var response = await client.GetAsync(fileUrl, HttpCompletionOption.ResponseHeadersRead);
stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);

var chunkSize = 4096 * 1024;
var buffer = new byte[chunkSize];

var byteRead = stream.Read(buffer, 0, chunkSize);

if (byteRead < chunkSize)
{
    // process the buffer as the only chunk
}
else
{
    // process initial chunk

    while (byteRead < chunkSize)
    {
        byteRead = stream.Read(buffer, 0, chunkSize);
        // process next chunks
    }
}

显然,此代码假定响应流将继续提供 4MB 块,直到到达最后一个块。但是我收到的流不是那样工作的。在这种情况下,处理此流的正确方法是什么?

【问题讨论】:

  • 通常 Stream.Read 可以返回任意数量的字节 >= 1 表示流未完成,或者返回 0 字节表示流已完成。所以你做一个 while ((bytesRead = stream.Read(buffer, 0, chunkSize)) > 0) { ... } 并快乐地生活。

标签: c# .net asp.net-core stream dotnet-httpclient


【解决方案1】:

我意识到流可以返回任意数量的字节,并且只有当它返回 0 字节时,才能将流视为已完成,如评论中所述。但是由于我的用例需要读取指定块大小的流,所以我想出了以下代码来读取它-

public static async Task<(int readCount, byte[] buffer)> ReadChunkAsync(Stream stream, int chunkSize)
{
    var buffer = new byte[chunkSize];
    var readCount = 0;

    while (readCount < chunkSize)
    {
        var bytesRead = await stream.ReadAsync(buffer, readCount, chunkSize - readCount);

        if (bytesRead == 0)
        {
            break;
        }

        readCount += bytesRead;
    }

    return (readCount, buffer);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 2018-12-21
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    相关资源
    最近更新 更多