問題描述:
項目需求將帶有中文名稱的多個文件壓縮至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();
}
}