C# 如何从http标头获取文件大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/122853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the file size from http headers
提问by
I want to get the size of an http:/.../file before I download it. The file can be a webpage, image, or a media file. Can this be done with HTTP headers? How do I download just the file HTTP header?
我想在下载之前获取 http:/.../file 的大小。该文件可以是网页、图像或媒体文件。这可以用 HTTP 标头完成吗?如何仅下载文件 HTTP 标头?
采纳答案by mdb
Yes, assuming the HTTP server you're talking to supports/allows this:
是的,假设您正在与之交谈的 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;
}
If using the HEAD method is not allowed, or the Content-Length header is not present in the server reply, the only way to determine the size of the content on the server is to download it. Since this is not particularly reliable, most servers will include this information.
如果不允许使用 HEAD 方法,或者服务器回复中不存在 Content-Length 标头,则确定服务器上内容大小的唯一方法是下载它。由于这不是特别可靠,大多数服务器都会包含此信息。
回答by Konrad Rudolph
Can this be done with HTTP headers?
这可以用 HTTP 标头完成吗?
Yes, this is the way to go. Ifthe information is provided, it's in the header as the Content-Length
. Note, however, that this is not necessarily the case.
是的,这是要走的路。如果提供了信息,则它在标题中作为Content-Length
. 但是,请注意,情况并非一定如此。
Downloading only the header can be done using a HEAD
request instead of GET
. Maybe the following code helps:
可以使用HEAD
请求而不是GET
. 也许以下代码有帮助:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://example.com/");
req.Method = "HEAD";
long len;
using(HttpWebResponse resp = (HttpWebResponse)(req.GetResponse()))
{
len = resp.ContentLength;
}
Notice the property for the content length on the HttpWebResponse
object –?no need to parse the Content-Length
header manually.
注意HttpWebResponse
对象内容长度的属性——不需要Content-Length
手动解析头部。
回答by Umut D.
WebClient webClient = new WebClient();
webClient.OpenRead("http://stackoverflow.com/robots.txt");
long totalSizeBytes= Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
Console.WriteLine((totalSizeBytes));
回答by Daria
Note that not every server accepts HTTP HEAD
requests. One alternative approach to get the file size is to make an HTTP GET
call to the server requesting only a portion of the file to keep the response small and retrieve the file size from the metadata that is returned as part of the response content header.
请注意,并非每个服务器都接受HTTP HEAD
请求。获取文件大小的另一种方法是HTTP GET
调用服务器,仅请求文件的一部分以保持响应较小,并从作为响应内容标头的一部分返回的元数据中检索文件大小。
The standard System.Net.Http.HttpClient
can be used to accomplish this. The partial content is requested by setting a byte range on the request message header as:
该标准System.Net.Http.HttpClient
可用于实现此目的。通过在请求消息头上设置字节范围来请求部分内容:
request.Headers.Range = new RangeHeaderValue(startByte, endByte)
The server responds with a message containing the requested range as well as the entire file size. This information is returned in the response content header (response.Content.Header
) with the key "Content-Range".
服务器以包含请求范围和整个文件大小的消息作为响应。此信息在响应内容标头 ( response.Content.Header
) 中返回,键为“Content-Range”。
Here's an example of the content range in the response message content header:
以下是响应消息内容标头中内容范围的示例:
{
"Key": "Content-Range",
"Value": [
"bytes 0-15/2328372"
]
}
In this example the header value implies the response contains bytes 0 to 15 (i.e., 16 bytes total) and the file is 2,328,372 bytes in its entirety.
在此示例中,标头值暗示响应包含字节 0 到 15(即总共 16 个字节),并且文件整体为 2,328,372 个字节。
Here's a sample implementation of this method:
这是此方法的示例实现:
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);
}
}
}
}