我想在下载文件之前获得http:/.../file的大小。该文件可以是网页、图像或媒体文件。这是否可以通过HTTP标头完成?如何仅下载文件的HTTP标头?
我想在下载文件之前获得http:/.../file的大小。该文件可以是网页、图像或媒体文件。这是否可以通过HTTP标头完成?如何仅下载文件的HTTP标头?
是的,假设你所访问的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头,则确定服务器上内容的大小的唯一方法是下载它。由于这种方法不太可靠,所以大多数服务器都会包含此信息。可以使用 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
标头。
resp.ContentLength
不会给你感兴趣的文件的大小,而是只会给你 HEAD 响应的长度。 - Adam NofsingerUsing
块或实现可处理模式来显式管理资源的生命周期。手动调用 Close
是不够的,除非你确保它 始终 发生,即使出现错误也是如此。 - Konrad RudolphContentLength
返回一个long
。虽然不是什么大问题,但以防万一你想修复它。 - gunr2171 request.Headers.Range = new RangeHeaderValue(startByte, endByte)
服务器响应包含请求范围和整个文件大小的消息。该信息在响应内容头(response.Content.Header
)中返回,使用键“Content-Range”。
以下是响应消息内容头中内容范围的示例:
{
"Key": "Content-Range",
"Value": [
"bytes 0-15/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);
}
}
}
}
WebClient webClient = new WebClient();
webClient.OpenRead("http://stackoverflow.com/robots.txt");
long totalSizeBytes= Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
Console.WriteLine((totalSizeBytes));
HttpClient client = new HttpClient(
new HttpClientHandler() {
Proxy = null, UseProxy = false
} // removes the delay getting a response from the server, if you not use Proxy
);
public async Task<long?> GetContentSizeAsync(string url) {
using (HttpResponseMessage responce = await client.GetAsync(url))
return responce.Content.Headers.ContentLength;
}
using
,它会自动处理资源的释放。详见:http://msdn.microsoft.com/zh-cn/library/yh598w02(v=vs.110).aspx - justderbint
类型可能不够,您需要使用long ContentLength;
并且使用long.TryParse(xxx)
来支持超过2.14GB大小返回值。 - Prestonhttp://ipv4.download.thinkbroadband.com/200MB.zip
,但是却收到了403错误!为什么? - Behzad