最近项目里需要做一个功能,就是吧多张图片压缩一个压缩文件,我使用的是java的ZipOutputStream 来实现的。最后开发完了,测试发现解压后的图片文件只有第一张能打开,后面的几张图片都打不开。
代码如下:
ZipOutputStream out = null;
BufferedOutputStream bo = null;
try{
out = new ZipOutputStream(new FileOutputStream(zipUrl));
bo = new BufferedOutputStream(out);
file = new File(fileUrl);
for(File tpfile:file.listFiles){
if(f.exits()){
String encodeHtml=encodeHtml(tpfile.getName());
out.putNextEntry(new ZipEntry(encodeHtml));
FileInputStream in = new FileInputStream(tpfile);
BufferedInputStream bi = new BufferedInputStream(in);
int b;
while((b=bi.read())!= -1){
bo.write(b);
}
bi.close();
in.close();
}
}catch(IOException e){
略..
}
bo.close();
out.close();
}
原因分析:
这里面比较重要的一行是
out.putNextEntry(new ZipEntry(encodeHtml));
这句的意思是压缩文件里面的一个文件开始的标志。所以出现这句时,证明开始压缩一个新的文件了,但是在开始新的文件压缩之前,发现bo.write(b) 后并没有bo.flush(),导致上一张图片还有数据在缓冲区没有被写到文件中去,所以进一步导致这部分还在缓冲区的数据被写到新的图片文件中,而且还是写在开头,所以直接导致后面的文件都无法打开。(注:BufferedOutputStream的buffer为8k,当buffer装满8k数据后就会写到磁盘文件中,如果不足8k,则不会写到磁盘文件中,此时只有使用flush方法才能让buffer的数据写到磁盘文件。)
所以解决的方法就是在bi.close();前加上bo.flush();即可