Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从http头中获取文件大小_C#_Http_Download_Http Headers - Fatal编程技术网

C# 如何从http头中获取文件大小

C# 如何从http头中获取文件大小,c#,http,download,http-headers,C#,Http,Download,Http Headers,我想在下载http:/…/文件之前获取其大小。该文件可以是网页、图像或媒体文件。这可以通过HTTP头完成吗?如何仅下载文件HTTP头 这可以通过HTTP头完成吗 是的,这就是路。如果提供了信息,则在标题中作为内容长度。但是,请注意,情况未必如此 只能使用HEAD请求而不是GET下载头。以下代码可能会有所帮助: HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://example.com/"); req.Method = "H

我想在下载http:/…/文件之前获取其大小。该文件可以是网页、图像或媒体文件。这可以通过HTTP头完成吗?如何仅下载文件HTTP头

这可以通过HTTP头完成吗

是的,这就是路。如果提供了信息,则在标题中作为
内容长度
。但是,请注意,情况未必如此

只能使用
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
头。

是,假设与您交谈的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头
请求。获取文件大小的另一种方法是向服务器发出
httpget
调用,只请求文件的一部分,以保持响应小,并从作为响应内容头一部分返回的元数据中检索文件大小

WebClient webClient = new WebClient();
webClient.OpenRead("http://stackoverflow.com/robots.txt");
long totalSizeBytes= Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
Console.WriteLine((totalSizeBytes));
可以使用标准的
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<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);
            }
        }
    }
}
公共静态类HttpClientExtensions
{
公共静态异步任务GetContentSizeAsync(此System.Net.Http.HttpClient客户端,字符串url)
{
使用(var request=new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get,url))
{
//为了使响应尽可能小,请将请求的字节范围设置为[0,0](即,仅第一个字节)
request.Headers.Range=new System.Net.Http.Headers.RangeHeaderValue(从:0到:0);
使用(var-response=await-client.sendsync(请求))
{
response.EnsureSuccessStatusCode();
if(response.StatusCode!=System.Net.HttpStatusCode.PartialContent)
抛出新的System.Net.WebException($“预期的部分内容响应({System.Net.HttpStatusCode.PartialContent}),而不是收到:{response.StatusCode}”);
var contentRange=response.Content.Headers.GetValues(@“Content Range”).Single();

var lengthString=System.Text.RegularExpressions.Regex.Match(contentRange,@)(?不会给出上面的头响应的长度,而不是您想要获得大小的文件的长度?@Adam No。文档说明:“ContentLength属性包含响应返回的Content Length标头的值。”请确保调用resp.Close(),否则在一次发出多个请求时可能会遇到超时错误(我的第三个请求在foreach循环中超时,通过关闭每个响应解决了此问题)@Eric事实上,您应该在此处使用
Using
块,或者实现一次性模式来显式管理资源的生存期。手动调用
Close
是不够的,除非您确保它总是发生,即使是在出错的情况下。@KonradRudolph您完全正确。调用Close()修复了我在测试时的错误,但是使用块是正确的方法。Derp。如果您使用
use
它会自动处理它。另一个注意事项,如果您对非常大的文件
int
使用它是不够的,您需要使用
long ContentLength;
long.TryParse(xxx)
支持超过2.14GB大小的返回值。启用http压缩不会影响实际文件大小吗?我使用此方法了解此链接的大小:
http://ipv4.download.thinkbroadband.com/200MB.zip
但出现错误403!为什么?这是一个很好的解决方案,特别是如果您已经在使用WebClient下载他创建了一个文件,只想先添加检查文件长度的功能。这是一个不错的解决方案,但并不是每台服务器都允许内容范围请求。