Неожиданный результат от HttpURLConnection - чтение удаленного двоичного файла - PullRequest
1 голос
/ 04 марта 2009

Я пытаюсь прочитать удаленный двоичный файл (скажем, изображение) из Интернета, как это:

HttpURLConnection connection = (HttpURLConnection) myUrl.openConnection(); //myUrl - URL object pointing for some location
if(connection.getResponseCode() == 200){
    File temp = File.createTempFile("blabla", fileName); //fileName - string name of file
    FileOutputStream out = new FileOutputStream(temp);
    int fileSize = Integer.parseInt(connection.getHeaderField("content-length"));
    int counter = 0;
    DataInputStream in = new DataInputStream(connection.getInputStream());
    byte ch[] = new byte[1024];
    System.out.println(counter);
    while((counter += in.read(ch)) > 0){
        out.write(ch);
        if(counter == fileSize){
            out.close();
            break;
        }
    }
}

Локально с локальным веб-сервером (localhost) он работает отлично.

Но. Тогда myUrl - это URL файла на некотором удаленном веб-сервере - он возвращает неожиданные результаты. Например, из источников данных файлов кажется, что он повторяет некоторые пакеты (я думаю, из-за повреждения предыдущих или некоторых), и результирующий файл обычно примерно на 10% больше исходного из-за этого повторяется. Таким образом, файл поврежден и не может быть правильно открыт средствами просмотра изображений.

Как я могу решить это?

1 Ответ

4 голосов
/ 04 марта 2009

read не обязательно считывает весь буфер (особенно, если он находится в конце потока).

Итак, измените ваш цикл:

for (;;) {
    int len = in.read(ch);
    if (len == -1) {
        break;
    }
    out.write(ch, 0, len);
}

Возможно, поместите этот код в метод где-нибудь.

Также обратите внимание:

  • Нет смысла использовать DataInputStream здесь (хотя readFully часто полезно).
  • Всегда закрывайте ресурс (например, потоки) с обычной идиомой:

    final Resource resource = acquire();
    try {
        use(resource);
    } finally {
        resource.close();
    }
    
  • Вероятно, не будет большой разницы, но размер буфера 1024 немного мал. Я склонен по умолчанию к 8192. Произвольно.

...