使用zip4j解压zip时文件名乱码解决最好的方案

本文介绍了在使用zip4j解压zip文件时遇到中文乱码问题的解决方案,通过检测文件名编码并动态选择UTF-8或GBK进行解压,以及对常见编码识别工具的评估。
摘要由CSDN通过智能技术生成

zip4j解压zip时,出现中文乱码,看了下,zip4j解压时支持设置文件编码,我们只需要识别文件是不是utf-8编码,如果不是utf-8就使用gbk解压,但是这个判断没有100%准确的方式,我试过通过字节流的bom标记去判断,但是文件不一定有bom字节,所以不适用。

网上最多的判断方式是使用第三方jar工具cpdetecpor或juniversalchardet,但是这两种方式我都尝试过,juniversalchardet无法判断出文件编码,而cpdetecpor可以得到一个判断结果,但是也不准确,我经过一两天的探索查找,找到了一个比较靠谱的方式:

    /**
     * 解压
     */
    @SneakyThrows
    public static void unzipFile(String zipFilePath, String destFilePath, String password) {
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(zipFilePath);
            zipFile.setCharset(StandardCharsets.UTF_8);
            List<FileHeader> headers = zipFile.getFileHeaders();
            //判断文件名是否有乱码,有乱码,将编码格式设置成GBK
            if (isRandomCode(headers)) {
                log.info("使用UTF-8解压文件【{}】时乱码,尝试使用GBK重新解压",zipFilePath);
                zipFile.close();
                zipFile = new ZipFile(zipFilePath);
                zipFile.setCharset(Charset.forName("GBK"));
            }
            if (!zipFile.isValidZipFile()) {
                throw new VerifyException("压缩文件不合法,可能被损坏.");
            }
            if (zipFile.isEncrypted() && StringTool.isNotBlank(password)) {//加密zip,且输入的密码不为空,直接进行解密。
                zipFile.setPassword(password.toCharArray());
            }
            FileTool.createDir(destFilePath);
            zipFile.extractAll(destFilePath);
        }finally {
            IOUtils.closeQuietly(zipFile,null);
        }
    }

    private static boolean isRandomCode(List<FileHeader> fileHeaders) {
        for (FileHeader fileHeader : fileHeaders) {
            boolean canEnCode = Charset.forName("GBK").newEncoder().canEncode(fileHeader.getFileName());
            if (!canEnCode) {//canEnCode为true,表示不是乱码。false.表示乱码。是乱码则需要重新设置编码格式
                return true;
            }
        }
        return false;
    }

我们先使用utf-8读取zip里面的文件名,然后判断文件名是否能使用gbk进行编码,如果不能,我们就用utf-8解压,如果gbk可以编码,就使用gbk进行解压

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值