将传入的文件列表统一打包成一个zip压缩包,依据需求也可对压缩包或压缩包内的文件重命名
/**
* 压缩ZIP
* @param srcFiles 需要压缩的文件列表
* @param out 压缩文件输出流,外部调用时也是对该输出流重命名
* @throws RuntimeException 压缩失败抛出异常
*/
public static void toZip(List<File> srcFiles, OutputStream out, List<String> fileName) throws RuntimeException {
long start = System.currentTimeMillis();
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(out);
for (int i = 0;i < srcFiles.size(); i++) {
System.out.println("准备压缩文件:" + srcFiles.get(i).getName() + ",路径:" + srcFiles.get(i).getPath());
byte[] buf = new byte[BUFFER_SIZE];
//对要压缩的文件重命名
zos.putNextEntry(new ZipEntry(fileName.get(i)));
int len;
FileInputStream in = new FileInputStream(srcFiles.get(i));
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}
zos.flush();
out.flush();
long end = System.currentTimeMillis();
System.out.println("压缩完成,耗时:" + (end - start) + " ms");
} catch (Exception ex) {
throw new RuntimeException("压缩错误", ex);
} finally {
if (zos != null) {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这里对后台压缩文件提供一个常用思路:开始运行时开启一个定时任务定期检测数据库列表中未处理的文件列表并进行异步压缩,开始压缩时更新一次压缩的记录为压缩中状态(写一个回调接口,调用压缩方法时传入实现类即可),避免压缩时间过长进入下一次循环时重复压缩,每次循环只对未压缩或压缩失败的记录进行重新压缩
另记录一个理论压缩方式:将文件流加入response的输出流中后让前端调用
(当文件稍大时就会出现需要等极长时间的情况,如果是做文件下载类的不推荐使用该方法)
压缩的方式到处都有,重要的还是要有业务逻辑思路