当前位置: 首页 > article >正文

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

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进行解压


http://www.kler.cn/a/229400.html

相关文章:

  • 【Vue3 入门到实战】1. 创建Vue3工程
  • vue3 uiapp实现一个数字输入组件, 舒服非数字会默认转成最小数
  • CT重建笔记(二)
  • HTML实战课堂之启动动画弹窗
  • 解决 VSCode 调试时 Python 文件出现相对路径报错问题‘FileNotFoundError’
  • Docker常用命令大全
  • c语言实现greedy snake(贪吃蛇)
  • 搭建游戏应该选择什么样的服务器?
  • JavaScript运行机制
  • 普通人应该如何使用GPT
  • 有趣的CSS - 输入框选中交互动效
  • word调整论文格式的记录
  • 第2节、让电机转起来【51单片机+L298N步进电机系列教程】
  • [C++] opencv + qt 创建带滚动条的图像显示窗口代替imshow
  • 亚马逊运营新手指南:10个基础概念解析
  • python大于等于怎么打?python运算符全详解!
  • MQ,RabbitMQ,SpringAMQP的原理与实操
  • C++ PE文件信息解析
  • LangChain pdf的读取以及向量数据库的使用
  • 一文掌握SpringBoot注解之@Configuration知识文集(5)
  • 【UE5 C++】超详细虚幻C++零基础学习教程
  • 爬虫实战--人民网
  • 60-JS-Ajax
  • 傅里叶变换在图像处理中的应用
  • QT QDialog 中的按钮,如何按下后触发 accepted 消息?
  • 《动手学深度学习(PyTorch版)》笔记6.3