问题描述:
项目需求将带有中文名称的多个文件压缩至zip包,并上传至linux服务器。采用jdk自带的ZipOutputStream输出流以压缩文件的格式写入文件,压缩文件上传成功之后,使用unzip命令解压缩zip包,发现带有中文名称的文件的文件名为乱码。
解决方案:
使用ZipArchiveOutputStream代替jdk自带的ZipOutputStream写入压缩文件
jar包依赖如下:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.5</version>
</dependency>
代码具体实现如下:
public static void zipFile(File[] allFiles){
String filePath = "/home/upload/test.zip";
File zipFile = new File(filePath);
ZipArchiveOutputStream zos = null;
try {
//创建写入文件的zip输出流
zos = new ZipArchiveOutputStream(zipFile);
zos.setEncoding("UTF8");
ZipEncoding zipEncoding = ZipEncodingHelper.getZipEncoding("UTF8");
if(allFiles !=null && allFiles.length>0){
for(File file:allFiles){
String fileName= file.getName();
ZipArchiveEntry zipEntry = new ZipArchiveEntry(file,fileName);
ByteBuffer byteBuffer = zipEncoding.encode(fileName);
//从给定的文件名称和字节数组组装unicode路径名称
UnicodePathExtraField unicodePathExtraField = new UnicodePathExtraField(fileName,byteBuffer.array(),byteBuffer.arrayOffset(),byteBuffer.limit()-byteBuffer.position());
zipEntry.addExtraField(unicodePathExtraField);
//将ZipArchiveEntry头部写入到输出流
zos.putArchiveEntry(zipEntry);
InputStream inputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
byte[] bufferByte = new byte[1024];
//读取文件内容
while(bufferedInputStream.read(bufferByte)>0){
zos.write(bufferByte);
}
//将文件数据写入
zos.closeArchiveEntry();
//关闭缓存输入流
bufferedInputStream.close();
}
}
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}