请注意,并非每个服务器都接受HTTP HEAD请求。获取文件大小的另一种方法是HTTP GET调用服务器,仅请求文件的一部分以使响应保持较小,并从作为响应内容标头的一部分返回的元数据中检索文件大小。
该标准System.Net.Http.HttpClient可用于完成此任务。通过将请求消息标头上的字节范围设置为以下内容来请求部分内容:
request.Headers.Range = new RangeHeaderValue(startByte, endByte)
服务器以一条包含所请求范围以及整个文件大小的消息作为响应。该信息response.Content.Header通过键“ Content-Range” 在响应内容头()中返回。
这是响应消息内容标头中内容范围的示例:
{
"Key": "Content-Range",
"Value": [
"bytes 0-15/2328372"
]
}
在此示例中,标头值表示响应包含0到15字节(即总共16个字节),并且文件整体为2328372字节。
这是此方法的示例实现:
public static class HttpClientExtensions
{
public static async Task GetContentSizeAsync(this System.Net.Http.HttpClient client, string url)
{
using (var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url))
{
// In order to keep the response as small as possible, set the requested byte range to [0,0] (i.e., only the first byte)
request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(from: 0, to: 0);
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
if (response.StatusCode != System.Net.HttpStatusCode.PartialContent)
throw new System.Net.WebException($"expected partial content response ({System.Net.HttpStatusCode.PartialContent}), instead received: {response.StatusCode}");
var contentRange = response.Content.Headers.GetValues(@"Content-Range").Single();
var lengthString = System.Text.RegularExpressions.Regex.Match(contentRange, @"(?<=^bytes\s[0-9]+\-[0-9]+/)[0-9]+$").Value;
return long.Parse(lengthString);
}
}
}
}