场景:解压xxxx.zip文件(如果zip文件里面嵌套zip,市面上工具基本不支持,自己写个递归方法即可),中文文件名出现乱码
工具:zip4j(默认编码集UTF-8)
乱码原因:
ZIP格式在不同平台上使用不同软件压缩:
1. Windows下使用WinRAR、好压、快压、百度压缩、360等工具压缩的文件 特点:文件名为GBK编码
2. 使用Linux、MacOS等系统压缩的zip文件 特点:文件名为UTF-8编码
maven配置信息:
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>2.7.0</version>
</dependency>解决方法:(直接上代码)
import com.google.common.collect.Lists;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* @author Angelo
* @date 2021/4/12 16:44
**/
public class ZipUtils {
private static final Logger logger = LoggerFactory.getLogger(ZipUtils.class);
private final static String RIGHT_SLASH = "/";
private final static String DOUBLE_LEFT_SLASH = "\\\\";
private final static String LEFT_SLASH = "\\";
private final static String CHARSET_GBK = "GBK";
/**
* 根据文件全路径将zip文件解压到一个文件路径下
* @param realPath
* @param dest
*/
public static List<UnZipInfo> unzip(String realPath, String dest){
try {
logger.info("解压开始:"+System.currentTimeMillis());
List<UnZipInfo> files = Lists.newArrayList();
ZipFile zipFile = new ZipFile(realPath);
zipFile.setCharset(Charset.forName(CHARSET_GBK));
zipFile.extractAll(dest);
// 获取ZIP中所有文件的FileHeader,以便后面对zip中文件进行遍历
List<FileHeader> list = zipFile.getFileHeaders();
logger.info("解压结束:"+System.currentTimeMillis());
list.forEach(fileHeadr->{
String fileName = fileHeadr.getFileName();
//zip压缩文件里面的文件列表
//如果是目录不做处理
if (fileName.endsWith(RIGHT_SLASH) || fileName.endsWith(DOUBLE_LEFT_SLASH) || fileName.endsWith(LEFT_SLASH)){
logger.info("这是一个文件夹:"+fileName);
}else {
//如果不是文件夹,将文件信息放入文件列表容器
UnZipInfo unZipInfo = new UnZipInfo();
unZipInfo.setFileOriginName(fileName);
unZipInfo.setRealAllPath(dest+File.separator+fileName);
files.add(unZipInfo);
}
});
return files;
} catch (ZipException e) {
logger.error("unzip file[{}] has error", realPath, e);
}
return null;
}
/**
* 前端传入File类型文件
* @param multipartFile
*/
public static List<UnZipInfo> unzipByFile(MultipartFile multipartFile){
try {
logger.info("解压开始:"+System.currentTimeMillis());
List<UnZipInfo> files = Lists.newArrayList();
//将存放在服务器的文件路径
String dateStr = String.valueOf(System.currentTimeMillis());
String tempDirectory = FileUtils.getTempDirectoryPath();
//Windows系统文件路径
String filePath = tempDirectory+File.separator+"Housing_System_Zip_"+dateStr;
logger.info("临时文件目录:"+tempDirectory+";压缩文件解压路径:"+filePath);
//multipartFile转成File
File file = new File(filePath+File.separator+multipartFile.getOriginalFilename());
FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
ZipFile zipFile = new ZipFile(file);
if (!testEncoding(filePath + File.separator + multipartFile.getOriginalFilename(), StandardCharsets.UTF_8)){
zipFile.setCharset(Charset.forName(CHARSET_GBK));
}
zipFile.extractAll(filePath);
// 获取ZIP中所有文件的FileHeader,以便后面对zip中文件进行遍历
List<FileHeader> list = zipFile.getFileHeaders();
list.forEach(fileHeadr->{
String fileName = fileHeadr.getFileName();
//zip压缩文件里面的文件列表
//如果是目录不做处理
if (fileName.endsWith(RIGHT_SLASH) || fileName.endsWith(DOUBLE_LEFT_SLASH) || fileName.endsWith(LEFT_SLASH)){
logger.info("这是一个文件夹:"+fileName);
}else {
//如果不是文件夹,将文件信息放入文件列表容器
UnZipInfo unZipInfo = new UnZipInfo();
unZipInfo.setFileOriginName(fileName);
unZipInfo.setRealAllPath(filePath+File.separator+fileName);
files.add(unZipInfo);
}
});
logger.info("解压结束:"+System.currentTimeMillis());
return files;
} catch (ZipException e) {
logger.error("unzipByFile file[{}] has error", multipartFile, e);
} catch (IOException e) {
logger.error("multipartFile to File has error", e);
}
return null;
}
/**
* 文件字符集判断
* @param filepath
* @param charset
* @return
* @throws FileNotFoundException
*/
private static boolean testEncoding(String filepath, Charset charset) throws FileNotFoundException {
FileInputStream fis = new FileInputStream(new File(filepath));
BufferedInputStream bis = new BufferedInputStream(fis);
ZipInputStream zis = new ZipInputStream(bis, charset);
ZipEntry zn = null;
try {
while ((zn = zis.getNextEntry()) != null) {
logger.info("check file charset");
}
} catch (Exception e) {
return false;
}finally {
try {
zis.close();
bis.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
}
版权声明:本文为booominng原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。