C#的HttpClient ReadAsStreamAsync

时间:2019-03-18 08:57:43

标签: c# httpclient

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

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

没有明显的原因使基普返回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);                           
}

1 个答案:

答案 0 :(得分:4)

这有点奇怪:

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

我希望您将刚刚读取的字节写入fileStream-即fileStream.Write(buffer, 0, read)本身。但是,您将缓冲区复制到data数组(不再使用),然后再次从流 中读取到buffer中(这次是同步的),并写入那个

因此,您将丢弃一半的下载字节。难怪“仅从427724800中读取了213864187个字节”!

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