Подтвердить что ты не робот

Java URLConnection: как узнать размер веб файла?

Я работаю над проектом для школы, и я реализую инструмент, который можно использовать для загрузки файлов из Интернета (с опцией дросселирования). Дело в том, что у меня будет GUI для этого, и я буду использовать виджет JProgressBar, который я бы хотел показать текущую версию загрузки. Для этого мне нужно знать размер файла. Как вы получаете размер файла перед загрузкой файла.

4b9b3361

Ответ 1

Любой HTTP-ответ должен содержать заголовок Content-Length, поэтому вы можете запросить объект URLConnection для этого значения.

//once the connection has been opened
List values = urlConnection.getHeaderFields().get("content-Length")
if (values != null && !values.isEmpty()) {

    // getHeaderFields() returns a Map with key=(String) header 
    // name, value = List of String values for that header field. 
    // just use the first value here.
    String sLength = (String) values.get(0);

    if (sLength != null) {
       //parse the length into an integer...
       ...
    }

Не всегда возможно, чтобы сервер возвращал точную Content-Length, поэтому значение может быть неточным, но, по крайней мере, вы могли бы получить некоторое полезное значение большую часть времени.

update: Или, теперь, когда я больше рассмотрю javadoc URLConnection, вы можете просто использовать getContentLength().

Ответ 2

Как уже упоминалось, URLConnection getContentLength - ваш лучший выбор, но он не всегда даст определенную длину. Это потому, что HTTP-протокол (и другие, которые могут быть представлены URLConnection) не всегда передает длину.

В случае HTTP длина динамического содержимого обычно неизвестна заранее, когда заголовок content-length обычно отправляется. Вместо этого другой заголовок transfer-coding указывает, что используется "закодированное" кодирование. При закодированном кодировании длина всего ответа не указывается, и ответ отправляется обратно в куски, где указан размер каждой части. На практике серверные буферы выводятся из сервлета. Всякий раз, когда буфер заполняется, отправляется другой кусок. Используя этот механизм, HTTP может фактически начать поток бесконечной длины.

Еще одна причина, по которой вы не сможете получить длину файла через URLConnection, - это если размер файла больше 2 Гб, что является предел для положительного целого числа.

Ответ 3

Используя запрос HEAD, я получил свой веб-сервер для ответа с правильным полем длины контента, которое в противном случае было пустым. Я не знаю, работает ли это вообще, но в моем случае это:

    private int tryGetFileSize(URL url) {
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("HEAD");
            conn.getInputStream();
            return conn.getContentLength();
        } catch (IOException e) {
            return -1;
        } finally {
            conn.disconnect();
        }
    }

Ответ 4

Вы хотите использовать длину содержимого (URLConnection.getContentLength()). К сожалению, это не всегда будет точным или может не всегда предоставляться, поэтому не всегда можно полагаться на него.

Ответ 5

    //URLConnection connection

private int FileSize(String url) {

 // this is the method and it get the url as a parameter.

       // this java class will allow us to get the size of the file.

        URLConnection con; 

         // its in a try and catch incase the url given is wrong or invalid

        try{ 

            // we open the stream

            con = new URL(url).openConnection()

            return con.getContentLength(); 
        }catch (Exception e){

            e.printStackTrace();

            // this is returned if the connection went invalid or failed.

            return 0; 
        }
    }

Ответ 6

Как сказал @erickson, иногда есть заголовок "Transfer-Encoding: chunked" вместо "Content-Length:" и, конечно, у вас есть нулевое значение для длины.

О методе available() - никто не может гарантировать вам, что он вернет правильное значение, поэтому я рекомендую вам не использовать его.