Java多word文件生成后进行压缩并导出下载后,压缩文件损坏并提示“不可预料的压缩文件末端”和“CRC校验失败”

Java多word文件生成后进行压缩并导出下载后,压缩文件损坏并提示“不可预料的压缩文件末端”和“CRC校验失败”

WinRAR 打开情况:
提示不可预料的压缩文件末端,实际情况是两个word文件,但是只显示了一个word文件,并无法打开word文件,提示“压缩文件已损坏”
提示不可预料的压缩文件末端,实际情况时两个word文件,但是只显示了一个word文件

好压 打开情况:
提示不可预料的压缩文件末端,word文件数量显示正确,并可以正常打开,因为好压自带了压缩文件损坏修复功能,WinRAR则需手动在菜单栏-工具-修复压缩文件进行修复即可正常使用
在这里插入图片描述

7-zip 打开情况:
可以打开,文件数量显示正常,可以看到图中第一个word文件的大小为0,此时打开该文件会提示“CRC校验失败”,第二个word文件可以正常打开。
在这里插入图片描述
在这里插入图片描述

问题分析:
在代码中,把事先生成好的多个文件逐步写入zip中,如果代码中没有编写zip的写入完成状态,那么就会出现此问题,通过图三分析可以推测出,只有一个word大小为0,其他的文件大小是正常的,经过断点调试发现总是最后一个文件压缩后大小显示为0,说明流的关闭完成环节出了问题

解决方案
在多文件写入zip文件,必须增加ZipOutputStream的finish()方法,例如:
(如果只是单个文件,只是用zipOutputStream.close()没有使用zipOutputStream.finish()也没有出现问题)

OutputStream bos = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream =  new ZipOutputStream(bos);
ByteArrayOutputStream output = new ByteArrayOutputStream();//ByteArray临时存储流

//此处documentMap是一个hashMap,Key值为文件名称,Value是对应XWPFDocument文件信息
Iterator<Map.Entry<String, XWPFDocument>> docIterator = documentMap.entrySet().iterator();
while (docIterator.hasNext()) {
	Map.Entry<String, XWPFDocument> entry = docIterator.next();
	XWPFDocument doc = entry.getValue();
	String key = entry.getKey();
	//如果对应的XWPFDocument文件信息不为空则写入到zip中
	if (null != doc) {
		//开始写入文件
		ZipEntry zipEntry = new ZipEntry(key +".docx");
		zipOutputStream.putNextEntry(zipEntry);
		output.reset();//重置ByteArray流(为了重复使用)
		doc.write(output);//把word对象内容写到ByteArray流临时存储
		doc.close();
		zipOutputStream.write(output.toByteArray());//把ByteArray流内容写入zip输出流
		zipOutputStream.closeEntry();
	}
}
output.close();
//结束写入文件
zipOutputStream.finish();
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值