V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
abstime
V2EX  ›  Java

文件上传后解压缩的问题

  •  
  •   abstime · 3 小时 0 分钟前 · 355 次点击

    开发中有个需求, 将一批 pdf 文件关联上多个物料, 现在的做法是通过

    1. 将这些文件合在一起做个压缩文件, 上传服务器解压;
    2. 然后通过文件名(物料编码)找对应的物料, 上传 oss 后将链接拿到和物料关联;

    在第 1 步解压上传的 MultipartFile 时出现的问题:

    java.lang.IllegalArgumentException: MALFORMED
    	at java.util.zip.ZipCoder.toString(ZipCoder.java:58)
    	at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:300)
    	at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:122)
    	at cn.hutool.core.util.ZipUtil.read(ZipUtil.java:664)
    	at cn.hutool.core.util.ZipUtil.unzip(ZipUtil.java:638)
    	at cn.hutool.core.util.ZipUtil.unzip(ZipUtil.java:624)
    

    以下为大致代码:

    import cn.hutool.core.util.ZipUtil;
    
    RestResponse uploadDiagram(@RequestParam MultipartFile file) {
            //  临时保存
            File tempDir = new File(configElement.getLocation() + "/" + DateTime.now().formatDateTime()  + "/");
            if (!tempDir.exists()) {
                tempDir.mkdirs();
            }
            ZipUtil.unzip(file.getInputStream(), tempDir, Charset.forName("UTF-8"));
            // 如果这个路径是文件夹
            if (tempDir.isDirectory()) {
                // todo 获取路径下的所有文件, 并上传 oss 获取链接
                }
            }
        }
    

    对话 ai 给出的问题分析和处理办法:

    1.文件路径或文件名格式错误:如果 ZIP 文件中包含中文或其他特殊字符,且在不同操作系统之间传输时,可能会因为编码不一致导致错误。例如,Windows 默认使用 GBK 编码,而 Linux 和 macOS 使用 UTF-8 编码。
    
    2.JDK 版本问题:在某些情况下,使用旧版本的 JDK 打包 ZIP 文件,然后在新版本的 JDK 上解压缩时可能会出现兼容性问题。
    
    3.hutool 版本问题:如果您使用的是 hutool 工具包,特定版本(如 5.8.11 至 5.8.16 )可能存在处理 ZIP 文件时的 bug ,导致解压缩时出现错误。升级到 5.8.17 或更高版本可以解决这个问题。
    
    针对这些问题,您可以尝试以下解决方案:
    
    检查和修改文件编码:确保 ZIP 文件中的文件名和路径使用正确的编码格式。您可以尝试将 ZIP 文件的编码格式改为与您的操作系统一致的编码,例如使用 GBK 或 UTF-8 。
    
    升级 hutool 版本:如果您使用的是 hutool ,升级到最新版本可能会解决这个问题。
    
    使用 Apache Commons Compress:Apache Commons Compress 提供了更好的跨平台兼容性,您可以尝试使用这个库来处理 ZIP 文件。
    
    捕获异常并处理:在代码中捕获 IllegalArgumentException 异常,并进行适当的错误处理。
    
    使用流的方式解压:有时候使用流的方式解压 ZIP 文件可以避免编码问题。
    

    尝试几种方式, 还是无法解决; 发现压缩文件中如果所有文件名文件夹没有中文和空格以及符号就可以正常运行 在此询问下如何解决这个问题或者有更合适的解决方案实现;

    7 条回复    2024-10-31 17:50:30 +08:00
    nm1st
        1
    nm1st  
       1 小时 33 分钟前
    看起来是编码的问题
    newaccount
        2
    newaccount  
       1 小时 5 分钟前
    没用过 hutool 包,纯猜
    ZipUtil.unzip(file.getInputStream(), tempDir, Charset.forName("UTF-8"));
    这个编码是指定的什么?解压缩时用到的编码吗?
    改成 gbk 试试,windows 默认文件名不是 UTF8 的
    “发现压缩文件中如果所有文件名文件夹没有中文和空格以及符号就可以正常运行”,这个建议分开测试,将中文、空格、符号分别测试,目的是排除空格和符号问题,将问题缩小到中文
    abstime
        3
    abstime  
    OP
       1 小时 1 分钟前
    @newaccount 试过 gbk 等其他编码还是行不通, 开发电脑用的 windows.
    newaccount
        4
    newaccount  
       58 分钟前
    @abstime 代码不变,压缩包的文件名用 UTF8 编码,包含中文试试
    cheng6563
        5
    cheng6563  
       49 分钟前
    打 7z 包吧
    jov1
        6
    jov1  
       35 分钟前
    之前用的 hutool 另外 api 解压,windows 和 linux 都正常运行,可以试下
    ```
    // 解压目录
    File extractFile = new File(extractPath);
    Extractor extractor = CompressUtil.createExtractor(
    CharsetUtil.CHARSET_GBK,
    FileUtil.file("d:/test/compress/test.zip"));

    extractor.extract(FileUtil.file(extractFile));
    // 获取目录 extractFile 下文件做其他处理。。。
    ```
    cowcomic
        7
    cowcomic  
       25 分钟前
    https://cloud.tencent.com/developer/article/1130020

    换解压缩工具吧,看来 hutool 的 ziputil 在处理跨平台压缩文件中含中文的情况时就是有这个毛病
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4115 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 10:15 · PVG 18:15 · LAX 03:15 · JFK 06:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.