我希望在下载之前获取http:/.../文件的大小。该文件可以是网页,图像或媒体文件。可以使用HTTP标头完成吗?如何仅下载文件HTTP标头?
答案 0 :(得分:90)
是的,假设你正在谈论的HTTP服务器支持/允许:
public long GetFileSize(string url)
{
long result = -1;
System.Net.WebRequest req = System.Net.WebRequest.Create(url);
req.Method = "HEAD";
using (System.Net.WebResponse resp = req.GetResponse())
{
if (long.TryParse(resp.Headers.Get("Content-Length"), out long ContentLength))
{
result = ContentLength;
}
}
return result;
}
如果不允许使用HEAD方法,或者服务器回复中不存在Content-Length标头,则确定服务器上内容大小的唯一方法是下载它。由于这不是特别可靠,大多数服务器都会包含此信息。
答案 1 :(得分:27)
可以使用HTTP标头吗?
是的,这是要走的路。 如果提供了信息,则它在标题中为Content-Length
。但请注意,情况不一定如此。
只能使用HEAD
请求而不是GET
来下载标头。也许以下代码有帮助:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://example.com/");
req.Method = "HEAD";
long len;
using(HttpWebResponse resp = (HttpWebResponse)(req.GetResponse()))
{
len = resp.ContentLength;
}
注意HttpWebResponse
对象上内容长度的属性 - 无需手动解析Content-Length
标题。
答案 2 :(得分:2)
WebClient webClient = new WebClient();
webClient.OpenRead("http://stackoverflow.com/robots.txt");
long totalSizeBytes= Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
Console.WriteLine((totalSizeBytes));
答案 3 :(得分:1)
请注意,并非每个服务器都接受HTTP HEAD
请求。获取文件大小的另一种方法是对服务器进行HTTP GET
调用,仅请求文件的一部分以保持响应较小,并从作为响应内容一部分返回的元数据中检索文件大小标头。
可以使用标准System.Net.Http.HttpClient
完成此操作。通过在请求消息头上将字节范围设置为以下内容来请求部分内容:
request.Headers.Range = new RangeHeaderValue(startByte, endByte)
服务器以一条消息响应,该消息包含所请求的范围以及整个文件大小。该信息通过键“ Content-Range”在响应内容标头(response.Content.Header
)中返回。
下面是响应消息内容标头中内容范围的示例:
{
"Key": "Content-Range",
"Value": [
"bytes 0-15/2328372"
]
}
在此示例中,标头值表示响应包含0到15个字节(即总共16个字节),文件的总大小为2328372字节。
这是此方法的示例实现:
public static class HttpClientExtensions
{
public static async Task<long> 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);
}
}
}
}