Неожиданный результат от HttpURLConnection - чтение удаленного двоичного файла
-
03-07-2019 - |
Вопрос
Я пытаюсь прочитать удаленный двоичный файл (скажем, изображение) из Интернета следующим образом:
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% больше исходного из-за этого повторения.Таким образом, файл поврежден и не может быть корректно открыт с помощью программы просмотра изображений.
Как я могу решить эту проблему?
Решение
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 произвольно.