C# 的 HttpClient ReadAsStreamAsync

Jor*_*gen 0 c# httpclient

我在使用 C# 的 HttpClient ReadAsStreamAsync 下载 400MB+ 文件时遇到问题 - 问题是从 427724800 中仅读取了大约 213864187 个字节,然后

read = await stream.ReadAsync(buffer, 0, buffer.Length, token)
Run Code Online (Sandbox Code Playgroud)

没有明显原因一直返回0。

有人遇到过类似的问题吗?

using (var stream = await response.Content.ReadAsStreamAsync()) {
    var totalRead = 0L;
    var buffer = new byte[4096];                            
    var moreToRead = true;

    const int CHUNK_SIZE = 4096;
    var fileStream = File.Create(filename, CHUNK_SIZE);                            
    int bytesRead;
        do {
        token.ThrowIfCancellationRequested();

        var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);

        if (read == 0) {
            moreToRead = false;
            this.Percentage = 100;
            if (fileStream != null) {
                    fileStream.Close();
                    fileStream.Dispose();
                }
        } else {
            var data = new byte[read];
            buffer.ToList().CopyTo(0, data, 0, read);
            bytesRead = stream.Read(buffer, 0, CHUNK_SIZE);
            if (bytesRead > 0) {                                       
                fileStream.Write(buffer, 0, bytesRead);
            }                                    
            // Update the percentage of file downloaded
            totalRead += read;

            if (canReportProgress) {
                var downloadPercentage = ((totalRead * 1d) / (total * 1d)) * 100;
                var value = Convert.ToInt32(downloadPercentage);
                this.Percentage = value;
                this.BytesReceived = totalRead;
            }
        }
    }
    while (moreToRead);                           
}
Run Code Online (Sandbox Code Playgroud)

can*_*on7 6

在这一点上发生了一些奇怪的事情:

buffer.ToList().CopyTo(0, data, 0, read);
bytesRead = stream.Read(buffer, 0, CHUNK_SIZE);
if (bytesRead > 0) {                                       
    fileStream.Write(buffer, 0, bytesRead);
} 
Run Code Online (Sandbox Code Playgroud)

我希望您将刚刚读入的字节写入fileStream- 即fileStream.Write(buffer, 0, read)自己。然而,你的缓冲区复制到一个data数组(这是永远不会再使用),然后从流中读取再次buffer(同步这段时间),并写

所以你扔掉了一半的下载字节。难怪“从 427724800 中只读取了大约 213864187 个字节”!

此外,using为您的使用块fileStream,而不是使用显式.Dispose()调用。此外,如果您要将一个数组复制到另一个数组,请使用Array.Copy而不是array.ToList().CopyTo(...).