Как получить размер файла из заголовков http
Я хочу получить размер http:/.../ файл перед его загрузкой. Файл может быть веб-страницей, изображением или мультимедийным файлом. Можно ли это сделать с помощью заголовков HTTP? Как я могу скачать просто в заголовке файла по HTTP?
4 ответа:
да, предполагая, что HTTP-сервер, с которым вы разговариваете, поддерживает/разрешает это:
System.Net.WebRequest req = System.Net.HttpWebRequest.Create("http://stackoverflow.com/robots.txt"); req.Method = "HEAD"; using (System.Net.WebResponse resp = req.GetResponse()) { int ContentLength; if(int.TryParse(resp.Headers.Get("Content-Length"), out ContentLength)) { //Do something useful with ContentLength here } }Если использование метода 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заголовок вручную.
WebClient webClient = new WebClient(); webClient.OpenRead("http://stackoverflow.com/robots.txt"); long totalSizeBytes= Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]); Console.WriteLine((totalSizeBytes));
обратите внимание, что не каждый сервер принимает
HTTP HEADзапросы. Одним из альтернативных подходов, чтобы получить размер файла, чтобы сделатьHTTP GETвызов сервера, запрашивающего только часть файла, чтобы сохранить ответ маленьким и получить размер файла из метаданных, которые возвращаются как часть заголовка содержимого ответа.стандартный
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 байт), а файл составляет 2,328,372 байта в своем полнота.
вот пример реализации этого метода:
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); } } } }