2009-09-25 22 views
7

Tengo un software que permite escribir complementos en archivos JavaScript (.js) que permiten usar la función Java (no sé si esto es común, nunca vi java call en javascript file before)Escribir un archivo descargado binario en un disco en Java

Necesito descargar un archivo binario de un servidor web y escribirlo en el disco duro. Probé el siguiente código:

baseencoder = new org.apache.commons.codec.binary.Base64(); 
url = new java.net.URL("https://server/file.tgz"); 

urlConnect = url.openConnection(); 
urlConnect.setDoInput(true); 
urlConnect.setDoOutput(true); 
urlConnect.setRequestProperty("authorization","Basic "+ java.lang.String(baseencoder.encodeBase64(java.lang.String(username + ":" + password).getBytes()))); 
urlConnect.setRequestProperty("content-type","application/x-www-form-urlencoded"); 

is = new java.io.DataInputStream(urlConnect.getInputStream()); 
fstream = new FileWriter("C:\\tmp\\test.tgz"); 
out = new BufferedWriter(fstream); 
while((data = is.read()) != -1){ 
    out.write(data); 
} 

out.close(); 
is.close(); 

El archivo resultante ya no es un archivo gzip válido. Lo siento si cometí un gran error, pero no soy un programador y no conozco demasiado Java.

Respuesta

33

No use un FileWriter - eso está tratando de convertir los datos en texto.

Simplemente use FileOutputStream.

byte[] buffer = new byte[8 * 1024]; 

InputStream input = urlConnect.getInputStream(); 
try { 
    OutputStream output = new FileOutputStream(filename); 
    try { 
    int bytesRead; 
    while ((bytesRead = input.read(buffer)) != -1) { 
     output.write(buffer, 0, bytesRead); 
    } 
    } finally { 
    output.close(); 
    } 
} finally { 
    input.close(); 
} 
+1

Además, querrá usar la condición de prueba correcta en su ciclo while: while ((data = ** is **. Read())! = Null) {...}. –

+0

Gracias al uso de FileOutputStream (todavía uso solo una lectura simple() porque parece que no es posible usar un búfer de bytes en javascript ya que no es un objeto. – radius

2

DataInputStream está destinado para la lectura de primitivos de Java, no para los datos genéricos.

También es redundante, ya que urlConnect.getInputStream(); ya devuelve un InputStream, y todos los InputStreams admiten read().

is = urlConnect.getInputStream(); 

P.S. Esto supone que is y bis son la misma variable. De lo contrario, estás leyendo la secuencia incorrecta en el ciclo.

+0

bis era un error tipográfico, lo corrigió, gracias. – radius

+0

Nice ¡Información! Es interesante saber que, a pesar de lo que sugieren los nombres, DataInputStream no es para datos genéricos ...! – Gewure

9

Sé que esta pregunta ya está respondida, pero un enfoque más simple es utilizar el método IOUtils.copy() de Apache Commons IO, que puede copiar completamente un InputStream en un OutputStream.

0

Acaba de leer acerca de LimitInputStream suena como lo hace exactamente lo que está haciendo, el buffer de la corriente de entrada para una mayor eficiencia.

Cuestiones relacionadas