Risultato imprevisto da HttpURLConnection - lettura del file binario remoto
-
03-07-2019 - |
Domanda
Sto cercando di leggere un file binario remoto (diciamo, immagine) da Internet in questo modo:
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;
}
}
}
A livello locale con server web locale (localhost) funziona perfettamente.
Ma. Quindi myUrl è l'URL del file su alcuni server Web remoti: restituisce risultati imprevisti. Ad esempio, dalle fonti di determinati file sembra che ripeta alcuni pacchetti (penso a causa della corruzione di quelli precedenti o qualcosa del genere) e il file risultante è di solito circa il 10% più grande di quello originale a causa di questo si ripete. Quindi il file è danneggiato e non può essere aperto correttamente con i visualizzatori di immagini.
Come posso risolvere questo?
Soluzione
read
non necessariamente legge l'intero buffer (in particolare se si trova alla fine dello stream).
Quindi cambia il tuo ciclo:
for (;;) {
int len = in.read(ch);
if (len == -1) {
break;
}
out.write(ch, 0, len);
}
Forse metti quel codice in un metodo da qualche parte.
Nota anche:
- Non ha senso usare
DataInputStream
qui (sebbenereadFully
sia spesso utile). -
Chiudi sempre la risorsa (come i flussi) con il solito linguaggio:
final Resource resource = acquire(); try { use(resource); } finally { resource.close(); }
-
Probabilmente non farà molta differenza, ma una dimensione del buffer di 1024 è un po 'piccola. Tendo a impostare 8192 in modo arbitrario.