Resultado inesperado do httpurlconnection - lendo arquivo binário remoto
-
03-07-2019 - |
Pergunta
Estou tentando ler um arquivo binário remoto (digamos, imagem) da Internet como esta:
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;
}
}
}
Localmente no servidor da web local (localhost), funciona perfeitamente.
Mas. Em seguida, o MYURL é URL do arquivo em algum servidor da Web remoto - ele retorna resultados inesperados. Por exemplo, a partir de fontes de arquivos especificados, parece que ele repete alguns pacotes (acho que por causa da corrupção dos anteriores ou de algum tempo) e o arquivo resultante geralmente é cerca de 10% maior que o original por causa disso. Portanto, o arquivo está corrompido e não pode ser aberto corretamente com os visualizadores de imagem.
Como posso resolver isso?
Solução
read
não lê necessariamente o buffer inteiro (principalmente se estiver no final do fluxo).
Então mude seu loop:
for (;;) {
int len = in.read(ch);
if (len == -1) {
break;
}
out.write(ch, 0, len);
}
Talvez coloque esse código em um método em algum lugar.
Observe também:
- Não faz sentido usar
DataInputStream
aqui (emborareadFully
é frequentemente útil). Sempre recurso próximo (como fluxos) com o idioma usual:
final Resource resource = acquire(); try { use(resource); } finally { resource.close(); }
Provavelmente não fará muita diferença, mas um tamanho de buffer de 1024 é um pouco pequeno. Costumo padrão para 8192 arbitrariamente.