2010-07-11 16 views
19

Estoy tratando de leer un archivo binario de un URLConnection. Cuando lo pruebo con un archivo de texto parece funcionar bien, pero para los archivos binarios no funciona. Estoy utilizando el siguiente tipo de mimo en el servidor cuando se envía el archivo:Lectura de archivo binario de URLConnection

application/octet-stream 

Pero hasta ahora nada parece funcionar. Este es el código que utilizo para recibir el archivo:

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(); 

Respuesta

34

esta es la forma en que lo hago,

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

La prueba 'n> 0' es innecesaria. De acuerdo con los javadocs, el único caso donde cero puede ser devuelto es cuando 'buffer.length' es cero. –

+5

... y en cualquier caso una escritura de longitud cero es inofensiva. – EJP

+0

Has guardado mi día :) –

14

Si usted está tratando de leer una secuencia binaria, usted no debe envolver la InputStream en un Reader de ningún tipo. Lea los datos en un búfer de matriz de bytes utilizando el método InputStream.read(byte[], int, int). Luego escriba desde el búfer a FileOutputStream.

La forma en que está leyendo/escribiendo actualmente el archivo lo convertirá en "caracteres" y volverá a los bytes utilizando la codificación de caracteres predeterminada de su plataforma. Esto es susceptible de destruir datos binarios.

(Hay un juego de caracteres (LATIN-1) que proporciona un mapeo sin pérdidas 1-a-1 entre bytes y un subconjunto del espacio de valores char.Sin embargo, esta es una mala idea incluso cuando la asignación funciona. se traduce/copiar los datos binarios de byte[] a char[] y vuelta a empezar ... que no logra nada en este contexto.)

+0

O puede tratar de concluir su InputStream en BufferedInputStream. – bhups

+1

@bhups: eso es cierto, pero solo ayudará si va a hacer muchas lecturas pequeñas. Si realiza lecturas de bloques grandes exclusivamente, un BufferedInputStream realmente reducirá el rendimiento un poco. –

+1

Esto es correcto; 'InputStreamReader' transformará los datos de bytes en datos de caracteres UTF-16 (en este caso, utilizando la codificación de plataforma predeterminada, que es una mala idea incluso para texto/normal). Un char de Java no es un octeto, como lo es en otros idiomas. – McDowell

Cuestiones relacionadas