打包文件到byte[]
因为公司业务需求,需要将一堆文件打包压缩成7z,然后响应给浏览器。压缩和解压缩的代码很多,都是到文件,需要磁盘的,我就不啰嗦了,我主要说下怎么打包成byte[]存在于内存中
File template = new File("E://new.pdf");
// 如果模板不存在,则不处理
if (!template.exists()) {
return;
}
// 把模板读进来
InputStream in = new FileInputStream(template);
byte[] data = toByteArray(in);
in.close();
//重点在这句
SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel();
//这个是写到文件
// SevenZOutputFile z7z = new SevenZOutputFile(new File(""));
//这个是写到内存中
SevenZOutputFile z7z = new SevenZOutputFile(channel);
SevenZArchiveEntry entry = null;
for (int i = 0; i < 20; i++) {
byte[] pdf = PDFUtils.creatrPDFByTemplate(data, single);
entry = new SevenZArchiveEntry();
entry.setName(String.valueOf(i) + System.currentTimeMillis() + ".pdf");
entry.setSize(pdf.length);
z7z.putArchiveEntry(entry);
z7z.write(pdf);
z7z.closeArchiveEntry();
System.out.printf("第%s个制作完成!\n", i);
}
z7z.close();
FileOutputStream file = new FileOutputStream("E://2.7z");
file.write(channel.array());
file.close();
因为我看到有下面这段代码,所以就去找了SeekableByteChannel,然后又被jdk中的这句java.nio.file.Files#newByteChannel给忽悠到了其他地方,越来越摸不着头脑,其实在org.apache.commons.compress.utils下面就有一个SeekableInMemoryByteChannel.java实现类
public SevenZOutputFile(final SeekableByteChannel channel) throws IOException {
this.channel = channel;
channel.position(SevenZFile.SIGNATURE_HEADER_SIZE);
}
写在最后:
感谢@meme大佬指点
附上项目依赖:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.16.1</version>
</dependency>
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.8</version>
</dependency>
上面的这种方式不适合大量数据,大佬给的建议是
数据比较大就要写盘缓存分段读比较好