Scrivere un file scaricato binario su disco in Java
-
16-09-2019 - |
Domanda
Ho un software che permette di scrivere add-on nel file JavaScript (.js) che permettono di utilizzare la funzione Java (non so se questo è comune, non ho mai visto chiamata java in javascript file prima)
Ho bisogno di scaricare un file binario da un server web e scrivere sul disco rigido. Ho provato il seguente codice:
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();
Il file risultante non è più un archivio gzip valida. Mi dispiace se ho fatto un errore enorme, ma io non sono un programmatore e non so Java troppo.
Soluzione
Non utilizzare un FileWriter
- che sta cercando di convertire i dati in testo
Basta usare 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();
}
Altri suggerimenti
So che questa domanda è già una risposta, ma un approccio più semplice è quello di utilizzare il metodo IOUtils.copy()
Apache Commons IO, che può copiare integralmente un InputStream
a un OutputStream
.
DataInputStream
è pensato per la lettura primitive Java, non per i dati generici.
E 'anche ridondante, come urlConnect.getInputStream();
restituisce già un InputStream, e tutti InputStreams supporto read ().
is = urlConnect.getInputStream();
P.S. Ciò presuppone is
e bis
sono la stessa variabile. In caso contrario, si sta leggendo il flusso di sbagliato nel ciclo.
Basta leggere su LimitInputStream suona come fa esattamente quello che stai facendo, il buffering del flusso di input per una maggiore efficienza.