Узнать размер файла из входящего потока

Задача:
Стягивать файл по ссылке, проверять его размер и передавать содержимое ответа дальше.

Код:

respGetFile, err := http.Get(urlFile)
if err != nil {
    return nil, err
}
defer respGetFile.Body.Close()

Вопрос:
Какой наименее ресурсозатратный метод, для получения размера файла, полученного из потока? На текущий момент приходит в голову только сохранять это как временный файл, получать его размер и после стирать.


Ответы (1 шт):

Автор решения: Pak Uula

В протоколе HTTP есть специальный запрос HEAD - это как GET, только возвращает ответ без тела. Но со всеми заголовками.

Вам достаточно сделать запрос HEAD и посмотреть заголовок Content-Length в ответе.

Вот пример программы, которая пользуется запросом HEAD и заголовком Content-Length для определения размера файла. Для примера выбран дистрибутив Ububtu, который точно не захочется качать для определения размера )

package main

import (
    "fmt"
    "net/http"
)

func main() {
    var clt = &http.Client{}
    urlFile := "http://mirror.yandex.ru/ubuntu-releases/18.04.4/ubuntu-18.04.4-desktop-amd64.iso"

    rsp, err := clt.Head(urlFile)
    if err != nil {
        fmt.Println("HEAD request failed", err)
        return
    } else {
        // по-хорошему, тут надо обработать статус запроса
        fmt.Println("File size", rsp.ContentLength)
    }
}

Результат работы программы: 2126544896

Я не скачивал для проверки, но вполне соответствует заявленным 2 гигабайтам.

Сразу скажу, что (а) не все сервера поддерживают заголовок HEAD, и (б) не все сервера отдают заголовок Content-Length при скачивании файла. Поэтому в общем случае этот метод не гарантирует правильный ответ. Конечно, вариант со скачиванием безопасней.

→ Ссылка