关于导出zip压缩包 以及相关流解释

对于压缩包的导出处理,我们一般会使用到三种流的操作
第一种:
	// 字节数组输出流,用于返回压缩后的输出流字节数组
	ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
	ByteArrayOutputStream 是一个输出流,数据写入其中会存储在内存中的字节数组中。
	它的主要作用就是将传入的数据存储在一个内部的字节数组中,能够动态扩展这个字节数组以容纳更多的数据。
第二种:
	// ZIP压缩输出流
	ZipOutputStream zip = new ZipOutputStream(byteOut);
	ZipOutputStream 是一个专门用于 ZIP 文件格式的输出流,它可以将多个文件/数据条目压缩并写入到底层输出流中。
	ZipOutputStream 使用底层输出流(在这种情况下是 ByteArrayOutputStream)实际就是存储压缩后的数据。
	
	当你创建 ZipOutputStream 时,将 ByteArrayOutputStream 作为参数传递给它:
	ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
	ZipOutputStream zip = new ZipOutputStream(byteOut);
	此时,ZipOutputStream 持有对 ByteArrayOutputStream 的引用,所有写入 ZipOutputStream 的数据最终都会通过 write() 方法传递给 ByteArrayOutputStream。
	
第三种:	
	// Servlet输出流
	OutputStream servletOut = response.getOutputStream();

ZipOutputStream 和 ByteArrayOutputStream 的关系

ZipOutputStream 是一个专门用于 ZIP 文件格式的输出流,它可以将多个文件/数据条目压缩并写入到底层输出流中。
	ZipOutputStream 使用底层输出流(在这种情况下是 ByteArrayOutputStream)实际就是存储压缩后的数据。
	当你创建 ZipOutputStream 时,将 ByteArrayOutputStream 作为参数传递给它:
	ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
	ZipOutputStream zip = new ZipOutputStream(byteOut);
	此时,ZipOutputStream 持有对 ByteArrayOutputStream 的引用,所有写入 ZipOutputStream 的数据最终都会通过 w

1.ByteArrayOutputStream和ZipOutputStream可以结合使用来将数据压缩为 ZIP 格式并写入到内存中的 byte 数组中。
ByteArrayOutputStream 用于将数据写入 byte 数组,而 ZipOutputStream 则用于将数据压缩为 ZIP 格式。

2.可以使用 zip.putNextEntry(new ZipEntry("test/订单" + i + ".xlsx")); 指定单条目录的名称
	putNextEntry代表单个条目数据,ZipEntry 用来指定信息

3.写入信息一般都会有一个叫 write 类的方法,比如 poi的XSSFWorkbook类
	把 XSSFWorkbook 的信息写入一个字节数组输出流中 ByteArrayOutputStream 就使用 XSSFWorkbook.write(ByteArrayOutputStream);
	XSSFWorkbook 的数据就会被写入到 ByteArrayOutputStream 字节数组中
	
4.把字节数组输出流中的数据,写入zip 中
	bos 就是一个独立的 ByteArrayOutputStream ,应为压缩包中的每个条目就是一个 ByteArrayOutputStream
	bos.writeTo(zip);
	通过 bos.writeTo(zip) 我们单条的数据就已经被写入到了 ZIP压缩输出流中。
	写入成功以后需要 zip.flush() 一下,这样可以 刷新压缩输出流 ,
	最后我们关闭当前这个条目,让流定位写入下一个条目 zip.closeEntry()。
	这样单条目数据就都处理完毕。
	
5.关闭流
	当单条数据写入完毕以后,ByteArrayOutputStream 就完成了使命,需要关闭他,
	这里可以使用 IOUtils.closeQuietly(bos),来关闭他。
	
6.总结
	当所有条目处理完毕以后,我们需要关闭当前的 zip 流 
	IOUtils.closeQuietly(zip); 这里需要注意一下:(转换byte[]前必须关闭zip流。)
	byte[] data = byteOut.toByteArray();    转为字节数组
	然后通过 HttpServletResponse.reset() 清除缓冲区数据。
	此时我们就可以 通过 HttpServletResponse 获取 Servlet输出流,把 byte[] data 的数据写入到 OutputStream 中了
	OutputStream servletOut = response.getOutputStream();
	这里可以使用 IOUtils 工具类的 write 方法 IOUtils.write(data, servletOut)。 把ZIP字节数组写入到Servlet输出流
	最后在关闭 ByteArrayOutputStream 字节数组输出流 以及 OutputStream Servlet输出流,这时我们就形成看完整的闭环。
	IOUtils.closeQuietly(byteOut);
    IOUtils.closeQuietly(servletOut);
	
7.关于压缩包信息设置
	在 response 中我们可以设置下载方式,文件名称
		response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".zip");
	设置文件下载总大小,前端可以通过这个显示下载进度条
		response.addHeader("Content-Length", "" + data.length);
	内容的内容类型及编码格式:application/octet-stream[二进制流]
		response.setContentType("application/octet-stream; charset=UTF-8");
	以及设置文件名称编码格式
		fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");

PS:这就完事了...
   还有一点,如果下载下来的压缩包是损坏的格式,那么可能是由于 流的关闭顺序不对导致的。



  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值