gpt4 book ai didi

c# - HttpClient - 下载前下载文件的大小

转载 作者:太空狗 更新时间:2023-10-29 21:27:38 24 4
gpt4 key购买 nike

我正在实现带进度条的文件下载。我正在使用 IAsyncOperationWithProgress 来解决这个问题,具体来说 this code .它工作得很好,但我只收到接收/下载的字节数。但我需要计算百分比来显示进度。这意味着我需要知道下载开始时的总字节数,但我没有找到有效执行此操作的方法。

以下代码解决进度报告。我尝试使用 responseStream.Length 获取流长度,但出现错误“此流不支持查找操作”。被抛出。

static async Task<byte[]> GetByteArratTaskProvider(Task<HttpResponseMessage> httpOperation, CancellationToken token, IProgress<int> progressCallback)
{
int offset = 0;
int streamLength = 0;
var result = new List<byte>();

var responseBuffer = new byte[500];

// Execute the http request and get the initial response
// NOTE: We might receive a network error here
var httpInitialResponse = await httpOperation;

using (var responseStream = await httpInitialResponse.Content.ReadAsStreamAsync())
{
int read;

do
{
if (token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
}

read = await responseStream.ReadAsync(responseBuffer, 0, responseBuffer.Length);

result.AddRange(responseBuffer);

offset += read;
// here I want to send percents of downloaded data
// offset / (totalSize / 100)
progressCallback.Report(offset);

} while (read != 0);
}

return result.ToArray();
}

你知道如何处理这个问题吗?或者您还有其他方法可以通过 HttpClient 下载带有进度报告的文件吗?我也尝试使用 BackgroundDownloader,但这对我来说还不够。谢谢。

最佳答案

您可以查看服务器返回的 Content-Length header 的值,该 header 存储在您的案例中 httpInitialResponse.Content.Headers 中。您必须使用相应的键(即“Content-Length”)在集合中找到 header

例如你可以这样做:

int length = int.Parse(httpInitialResponse.Content.Headers.First(h => h.Key.Equals("Content-Length")).Value.First());

(您必须首先确保服务器已发送 Content-Length header ,否则上面的行将失败并出现异常)

您的代码如下所示:

static async Task<byte[]> GetByteArrayTaskProvider(Task<HttpResponseMessage> httpOperation, CancellationToken token, IProgress<int> progressCallback)
{
int offset = 0;
int streamLength = 0;
var result = new List<byte>();

var responseBuffer = new byte[500];

// Execute the http request and get the initial response
// NOTE: We might receive a network error here
var httpInitialResponse = await httpOperation;
var totalValueAsString = httpInitialResponse.Content.Headers.SingleOrDefault(h => h.Key.Equals("Content-Length"))?.Value?.First());
int? totalValue = totalValueAsString != null ? int.Parse(totalValueAsString) : null;

using (var responseStream = await httpInitialResponse.Content.ReadAsStreamAsync())
{
int read;
do
{
if (token.IsCancellationRequested)
{
token.ThrowIfCancellationRequested();
}

read = await responseStream.ReadAsync(responseBuffer, 0, responseBuffer.Length);
result.AddRange(responseBuffer);

offset += read;
if (totalSize.HasValue)
{
progressCallback.Report(offset * 100 / totalSize);
}
//for else you could send back the offset, but the code would become to complex in this method and outside of it. The logic for "supports progress reporting" should be somewhere else, to keep methods simple and non-multi-purpose (I would create a method for with bytes progress and another for percentage progress)
} while (read != 0);
}
return result.ToArray();
}

关于c# - HttpClient - 下载前下载文件的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24349478/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com