Escrever um arquivo baixado binária no disco em Java
-
16-09-2019 - |
Pergunta
Eu tenho um software que permitem a gravação add-on em arquivos JavaScript (.js) que permitem utilizar a função de Java (eu não sei se isso é comum, eu nunca vi chamada java no arquivo javascript antes)
Eu preciso baixar um arquivo binário a partir de um servidor web e escrevê-lo para o disco rígido. Eu tentei o seguinte 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();
O arquivo resultante não é mais um arquivo gzip válido. Me desculpe se eu fiz um grande erro, mas eu não sou um programador e não sei Java muito.
Solução
Não use um FileWriter
-. que está tentando converter os dados em texto
Apenas uso 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();
}
Outras dicas
Eu sei que esta pergunta já foi respondida, mas uma abordagem mais simples é usar o método IOUtils.copy()
do Apache Commons IO, que pode copiar integralmente uma InputStream
a um OutputStream
.
DataInputStream
é destinado a leitura primitivos Java, e não para dados genéricos.
Também é redundante, como urlConnect.getInputStream();
já retorna um InputStream, e todos os InputStreams apoio read ().
is = urlConnect.getInputStream();
P.S. Isso supõe que is
e bis
são a mesma variável. Caso contrário, você está lendo o fluxo de errado no circuito.
Apenas ler sobre sons LimitInputStream como ele faz exatamente o que você está fazendo, tamponamento do fluxo de entrada para uma maior eficiência.