前言
最近有个需求需要将批量生成二维码并打包,业务逻辑开发完成后,测试发现打包过程比较慢,100个二维码达成压缩包需要3-5s。于是想使用多线程来打包,于是就发现commons-compress有现成的多线程打包方案。
原始方案压缩
/**
* 压缩文件
*
* @param out 压缩文件夹输出流
* @param inputStream 需要压缩的数据
* @param zipEntryName 单项文件名称
*/
public static void put(ZipOutputStream out, InputStream inputStream, String zipEntryName) throws IOException {
out.putNextEntry(new ZipEntry(zipEntryName));
int len;
byte[] buffer = new byte[2048];
while ((len = inputStream.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.closeEntry();
}
直接使用ZipOutputStream进行打包二维码图片
原始apache-compress压缩
引入依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
压缩方法
public static void compressTaskList(OutputStream outputStream, List<CustomFutureTask<Tuple2<BufferedImage, String>>> futureTaskList) throws Exception {
ParallelScatterZipCreator parallelScatterZipCreator = new ParallelScatterZipCreator(EXECUTOR);
ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(outputStream);
zipArchiveOutputStream.setEncoding(StandardCharsets.UTF_8.name());
for (int i = 0; i < futureTaskList.size(); i++) {
final Tuple2<BufferedImage, String> image = futureTaskList.get(i).get();
final InputStreamSupplier inputStreamSupplier = () -> bufferedImageToInputStream(image.getT1());
ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(image.getT2());
zipArchiveEntry.setMethod(ZipArchiveEntry.DEFLATED);
zipArchiveEntry.setUnixMode(UnixStat.DEFAULT_FILE_PERM);
parallelScatterZipCreator.addArchiveEntry(zipArchiveEntry, inputStreamSupplier);
}
parallelScatterZipCreator.writeTo(zipArchiveOutputStream);
zipArchiveOutputStream.close();
outputStream.close();
}
结果
通过优化后压缩提高很多,基本是秒下,感觉不到延迟。