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

Объединив динамическое решение Ege с идеей Vinay, вы получите хорошее надежное решение:

Array.prototype.sortBy = function() {
    function _sortByAttr(attr) {
        var sortOrder = 1;
        if (attr[0] == "-") {
            sortOrder = -1;
            attr = attr.substr(1);
        }
        return function(a, b) {
            var result = (a[attr] < b[attr]) ? -1 : (a[attr] > b[attr]) ? 1 : 0;
            return result * sortOrder;
        }
    }
    function _getSortFunc() {
        if (arguments.length == 0) {
            throw "Zero length arguments not allowed for Array.sortBy()";
        }
        var args = arguments;
        return function(a, b) {
            for (var result = 0, i = 0; result == 0 && i < args.length; i++) {
                result = _sortByAttr(args[i])(a, b);
            }
            return result;
        }
    }
    return this.sort(_getSortFunc.apply(null, arguments));
}

Использование:

// Utility for printing objects
Array.prototype.print = function(title) {
    console.log("************************************************************************");
    console.log("**** "+title);
    console.log("************************************************************************");
    for (var i = 0; i < this.length; i++) {
        console.log("Name: "+this[i].FirstName, this[i].LastName, "Age: "+this[i].Age);
    }
}

// Setup sample data
var arrObj = [
    {FirstName: "Zach", LastName: "Emergency", Age: 35},
    {FirstName: "Nancy", LastName: "Nurse", Age: 27},
    {FirstName: "Ethel", LastName: "Emergency", Age: 42},
    {FirstName: "Nina", LastName: "Nurse", Age: 48},
    {FirstName: "Anthony", LastName: "Emergency", Age: 44},
    {FirstName: "Nina", LastName: "Nurse", Age: 32},
    {FirstName: "Ed", LastName: "Emergency", Age: 28},
    {FirstName: "Peter", LastName: "Physician", Age: 58},
    {FirstName: "Al", LastName: "Emergency", Age: 51},
    {FirstName: "Ruth", LastName: "Registration", Age: 62},
    {FirstName: "Ed", LastName: "Emergency", Age: 38},
    {FirstName: "Tammy", LastName: "Triage", Age: 29},
    {FirstName: "Alan", LastName: "Emergency", Age: 60},
    {FirstName: "Nina", LastName: "Nurse", Age: 54}
];

//Unit Tests
arrObj.sortBy("LastName").print("LastName Ascending");
arrObj.sortBy("-LastName").print("LastName Descending");
arrObj.sortBy("LastName", "FirstName", "-Age").print("LastName Ascending, FirstName Ascending, Age Descending");
arrObj.sortBy("-FirstName", "Age").print("FirstName Descending, Age Ascending");
arrObj.sortBy("-Age").print("Age Descending");
29
задан Patrick W. McMahon 1 February 2015 в 20:28
поделиться

6 ответов

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

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

38
ответ дан Xavi López 1 February 2015 в 20:28
поделиться

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

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

Если размер файла превышает 2 ГБ, его размер не может быть представлен как int, поэтому более старый метод, getContentLength() вернет -1 в этом случае.

33
ответ дан erickson 1 February 2015 в 20:28
поделиться

Используя запрос 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();
        }
    }
28
ответ дан betty 1 February 2015 в 20:28
поделиться

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

4
ответ дан Herms 1 February 2015 в 20:28
поделиться
    //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; 
        }
    }
1
ответ дан mcgowan.b 1 February 2015 в 20:28
поделиться

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

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

0
ответ дан Petromir Dzhunev 1 February 2015 в 20:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: