Passei essa semana por esse problema em um projeto no trabalho.
O caso era realizar o download de um arquivo, no android. O problema era que apesar da conexão estar certa, o arquivo era salvo errado, os bytes estavam errados apesar do tamanho esta quase certo.
Acontece que usei um algorimo básico para baixar escrever no arquivo, primeiro fazia a coneão HTTP:
URL urlCn = new URL(url.toString().trim());
HttpURLConnection conn = (HttpURLConnection) urlCn.openConnection();
conn.setDoInput(true);
E em seguida criava o arquivo:
File file = new File("downloads", name );
if(!file.exists()) {
try {
file.createNewFile();
isNew = true;
} catch (IOException e) {
e.printStackTrace();
return;
}
}
Então chegava a problemática hora de escrever o conteúdo do arquivo, eu estava usando um algorimo básico, que sempre funciona com InputStreams locais.
int bSize = 1 * 1024 ;
FileOutputStream fos = null;
BufferedInputStream bis = new BufferedInputStream(is,bSize);
try {
fos = new FileOutputStream(file);
byte[] buffer = new byte[bSize];
while(bis.read(buffer) > 0) {
fos.write(buffer);
}
fos.flush();
fos.close();
bis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
O algorismo lê, a cada "bSize" e escreve no arquivo, para não ocupar muita memória.
A pegadinha esta em que nem sempre o InputStream da conexão me retorna a quantidade de bytes que eu pedi, mas eu sempre estava escrevendo o buffer inteiro. Logo se num buffer de 1k, o Stream só me deu 512B, eu estava escrevendo o resto de lixo (bytes da escrita antiga).
A correção foi alterar o trecho para o código a seguir:
int len1 = 0;
while((len1 = bis.read(buffer)) > 0 ) {
fos.write(buffer, 0,len1);
}
E todos viveram felizes para sempre.
- Comments





