主要参考文章A:Android 下载文件 显示进度条,并做了部分修改。
使用文章A的代码,运行后,下载的文件,在手机上提示“文件格式不对或者文件已损坏”,
造成该问题的代码段:
1 /* 2 * 向SD卡中写入文件,用Handle传递线程 3 */ 4 Message message=new Message(); 5 try { 6 outputStream=new FileOutputStream(file); 7 byte [] buffer=new byte[1024*4]; 8 FileLength=connection.getContentLength(); 9 message.what=0; 10 handler.sendMessage(message); 11 while (DownedFileLength<FileLength) { 12 outputStream.write(buffer); //!!!!!! 13 DownedFileLength+=inputStream.read(buffer); 14 Log.i("-------->", DownedFileLength+""); 15 Message message1=new Message(); 16 message1.what=1; 17 handler.sendMessage(message1); 18 }
修改为:
1 /* 向SD卡中写入文件,用Handle传递线程 2 */ 3 Message message=new Message(); 4 try { 5 outputStream=new FileOutputStream(file); //写入文件;文件字节输出流,专用于输出原始字节流如图像数据等 6 byte [] buffer=new byte[1024*4];//1024*4 //定义一个字节数组,相当于缓存 7 FileLength=connection.getContentLength(); 8 message.what=0; 9 handler.sendMessage(message); 10 //System.out.println("FileLength:"+FileLength); 11 int count=0; //得到实际读取到的字节数 读到最后返回-1 12 while ((count = inputStream.read(buffer)) > 0) {//DownedFileLength<FileLength 把inputStream里的东西读到bytes数组里去 13 //outputStream.write(buffer); 14 //System.out.println("len:"+len); 15 outputStream.write(buffer,0,count); 16 DownedFileLength+=count; //inputStream.read(buffer) 17 Log.i("---DownedFileLength--->", DownedFileLength+" >"); 18 Message message1=new Message(); 19 message1.what=1; 20 handler.sendMessage(message1); 21 }
outputStream.write(buffer,0,count); 读多少位写多少。不会出现文件损坏的情况!!!
原因:
----每次填充往缓冲数组中填充1024字节,当循还到最后一次的时候流中已经没有1024个字节了,比如最后一次只有100个了,那么会填充缓冲数组的前100个位置字节,那么100以后位置的字节就是保留了上一次的字节,所以写入文件的时候,字节已经错乱了,所以你打开的时候就报错了。
----outputStream.write(buffer, 0, len);这个的意思是将buffer里面0~len的字节写到输出流里面,下载的文件转换成字节流的字节数一般是不能被1024整除的,当输出最后一部分字节的时候,可能没有1024个字节,那么buffer字节数组里多出来的位置就是初始值0,这些也写到输出流里面去了,也就是多写了很多个值为0的字节进去,所以格式不对。
参考
java IO流下载.docx文件时报文件损坏的错误,求解?
进度条:
Android 进度条 .xml设置进度条 <ProgressBar /> 已使用
Android ProgressBar进度条,以及自定义显示 进度条,进度颜色自定义
Android 常见进度条---合集 LProgressView 看起来不错 Android实现百分比下载进度条效果 自定义进度条
其他
只是在内存中开辟块缓冲区而已。大小随便写,只要不超过你实际可用内存大小就好。
不过太大或者太小都会对性能有影响。
所以通常采用 4 的倍数,或者 1K 的倍数作为buffer,有利于较少内存碎片