2010-07-11 26 views
19

Sto provando a leggere un file binario da un URLConnection. Quando lo provo con un file di testo sembra funzionare bene, ma per i file binari non è così. Sto utilizzando il seguente tipo MIME sul server quando il file viene inviare:Lettura file binario da URLConnection

application/octet-stream 

Ma finora nulla sembra funzionare. Questo è il codice che uso per ricevere il file:

file = File.createTempFile("tempfile", ".bin"); 
file.deleteOnExit(); 

URL url = new URL("http://somedomain.com/image.gif"); 

URLConnection connection = url.openConnection(); 

BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream())); 

Writer writer = new OutputStreamWriter(new FileOutputStream(file)); 

int c; 

while((c = input.read()) != -1) { 

    writer.write((char)c); 
} 

writer.close(); 

input.close(); 

risposta

34

questo è come lo faccio,

input = connection.getInputStream(); 
byte[] buffer = new byte[4096]; 
int n; 

OutputStream output = new FileOutputStream(file); 
while ((n = input.read(buffer)) != -1) 
{ 
    output.write(buffer, 0, n); 
} 
output.close(); 
+7

Il test 'n> 0' non è necessario. Secondo javadocs, l'unico caso in cui può essere restituito zero è quando 'buffer.length' è zero. –

+5

... e in ogni caso una scrittura di lunghezza zero è innocua. – EJP

+0

Hai salvato la mia giornata :) –

14

Se si sta tentando di leggere un flusso binario, si dovrebbe Non avvolgere il InputStream in un Reader di qualsiasi tipo. Leggere i dati in un buffer di array di byte utilizzando il metodo InputStream.read(byte[], int, int). Quindi scrivere dal buffer su FileOutputStream.

Il modo in cui state leggendo/scrivendo il file lo convertirà in "caratteri" e tornerà ai byte usando la codifica dei caratteri predefinita della vostra piattaforma. Questo è soggetto a manipolare dati binari.

(C'è un set di caratteri (LATIN-1) che fornisce un mapping lossless 1-a-1 tra byte e un sottoinsieme dello spazio-valore char. Tuttavia questa è una cattiva idea anche quando la mappatura funziona. essere traducendo/copiare i dati binari dal byte[] a char[] e viceversa ... che realizza nulla in questo contesto.)

+0

Oppure si può provare avvolgendo il tuo InputStream in BufferedInputStream. – bhups

+1

@bhups: è vero, ma sarà utile solo se si stanno facendo molte letture di piccole dimensioni. Se si eseguono esclusivamente letture di blocchi di grandi dimensioni, un BufferedInputStream riduce effettivamente il throughput un po '. –

+1

Questo è corretto; 'InputStreamReader' trasformerà i dati di byte in dati di carattere UTF-16 (in questo caso, utilizzando la codifica di piattaforma predefinita, che è una cattiva idea anche per testo/plain). Un char Java non è un ottetto come in altre lingue. – McDowell