实际上,有很多相关的博客,但我测试了很多都 会出现两个问题,为避免新手踩坑而写
问题:
1、压缩完成后出现没有关闭流的现象(循环分别创建流对象未关闭导致)
2、压缩多级目录失效,只压缩部分文件(递归导致创建出多个压缩输出流对象)
解决如下:
/**
* 压缩多文件
*
* @param files 多个文件
* @param basePath 压缩文件内的相对路径
* @param zipFile 压缩文件
* @throws IOException 异常
*/
public static void zip(File[] files, String basePath, File zipFile) throws IOException {
if (files == null || files.length == 0) return;
FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
try {
procesZip(zos, files, basePath);
} finally {
closeStream(zos, fos); //关闭压缩流,输出流
}
}
/**
* 处理压缩,该部分抽离出来主要是为了保证 压缩输出流 不会多创建
*
* @param zos 压缩输出流
* @param files 文件数组
* @param basePath 压缩文件内的相对路径
* @throws IOException 异常
*/
private static void procesZip(ZipOutputStream zos, File[] files, String basePath) throws IOException {
int count;// 数目
final byte[] buffer = new byte[2048]; //缓冲
for (File file : files) {
if (file.isDirectory()) {
procesZip(zos, file.listFiles(), basePath + File.separator + file.getName());// 递归
continue;
}
zos.putNextEntry(new ZipEntry(basePath + File.separator + file.getName()));// 加入
FileInputStream fis = new FileInputStream(file);// 输入
// 读取
while ((count = fis.read(buffer, 0, buffer.length)) != -1) {
zos.write(buffer, 0, count);// 写入
}
zos.closeEntry();// 释放资源
fis.close(); //关闭输入流
}
}
/**
* 关闭流
*
* @param closeables 不定长数组 流对象
*/
public static void closeStream(Closeable... closeables) {
for (Closeable closeable : closeables) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}