Как получить размер файла из заголовков http

Я хочу получить размер файла http: /.../ перед его загрузкой. Файл может быть веб-страницей, изображением или медиафайлом. Можно ли это сделать с помощью заголовков HTTP? Как загрузить только HTTP-заголовок файла?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
67
0
54 354
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Can this be done with HTTP headers?

Да, это правильный путь. Если информация предоставлена, она в заголовке как 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, а не длину файла, который вы хотели получить, sizeof?

Adam Nofsinger 19.04.2011 16:47

@Adam Нет. В документации говорится: «Свойство ContentLength содержит значение заголовка Content-Length, возвращаемого с ответом».

Konrad Rudolph 19.04.2011 16:57

Убедитесь, что вы вызываете resp.Close (), иначе вы можете столкнуться с ошибками тайм-аута при одновременном выполнении нескольких запросов (мой третий запрос был отключен в цикле foreach, который был решен путем закрытия каждого ответа)

Eric Smith 26.03.2013 00:56

@Eric На самом деле вы должны использовать здесь блок Using или реализовать одноразовый шаблон для явного управления временем жизни ресурса. Вызов Close вручную недостаточно, если вы не уверены, что произойдет всегда, даже в случае ошибки.

Konrad Rudolph 26.03.2013 00:59

@KonradRudolph Вы абсолютно правы. Вызов Close () исправил мою ошибку, пока я тестировал это, но использование блока - правильный способ сделать это. Дерп.

Eric Smith 26.03.2013 04:59

@KonradRudolph, к сведению, ContentLength возвращает long. Ничего страшного, но на всякий случай, если вы захотите это исправить.

gunr2171 02.05.2013 04:14
Ответ принят как подходящий

Да, при условии, что 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 отсутствует в ответе сервера, единственный способ определить размер содержимого на сервере - загрузить его. Поскольку это не особенно надежно, большинство серверов будут включать эту информацию.

Если вы используете using, он автоматически удаляется. msdn.microsoft.com/en-us/library/yh598w02(v=vs.110).aspx

justderb 17.04.2013 00:12

Еще одно замечание: если вы используете это для очень больших файлов, int недостаточно, вам нужно использовать long ContentLength; и long.TryParse(xxx) для поддержки возвращаемого значения размером более 2,14 ГБ.

Preston 16.10.2015 07:27

Не приведет ли включение HTTP-сжатия к фактическому размеру файла?

Justin 18.07.2016 02:06

Я использую этот метод, чтобы узнать размер этой ссылки: http://ipv4.download.thinkbroadband.com/200MB.zip, но получаю ошибку 403! Почему?

Behzad 21.04.2020 14:31

WebClient webClient = new WebClient();
webClient.OpenRead("http://stackoverflow.com/robots.txt");
long totalSizeBytes= Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
Console.WriteLine((totalSizeBytes));

Это отличное решение, особенно если вы уже используете WebClient для загрузки файла и просто хотите сначала добавить проверку длины файла.

ScottFoster1000 22.10.2018 22:34

Обратите внимание, что не каждый сервер принимает запросы 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);
            }
        }
    }
}

Хорошее решение, но не каждый сервер разрешает запросы диапазона контента.

Phani Rithvij 29.12.2019 16:21

Другие вопросы по теме