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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 14:36:23  来源:igfitidea点击:

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 HEADrequest 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 HttpWebResponseobject –?no need to parse the Content-Lengthheader 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 HEADrequests. One alternative approach to get the file size is to make an HTTP GETcall 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.HttpClientcan 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);
            }
        }
    }
}