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

文件上传后解压缩的问题

  •  
  •   abstime · 57 天前 · 1445 次点击
    这是一个创建于 57 天前的主题,其中的信息可能已经有所发展或是发生改变。

    开发中有个需求, 将一批 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 文件可以避免编码问题。
    

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

    15 条回复
    nm1st
        1
    nm1st  
       57 天前
    看起来是编码的问题
    newaccount
        2
    newaccount  
       57 天前
    没用过 hutool 包,纯猜
    ZipUtil.unzip(file.getInputStream(), tempDir, Charset.forName("UTF-8"));
    这个编码是指定的什么?解压缩时用到的编码吗?
    改成 gbk 试试,windows 默认文件名不是 UTF8 的
    “发现压缩文件中如果所有文件名文件夹没有中文和空格以及符号就可以正常运行”,这个建议分开测试,将中文、空格、符号分别测试,目的是排除空格和符号问题,将问题缩小到中文
    abstime
        3
    abstime  
    OP
       57 天前
    @newaccount 试过 gbk 等其他编码还是行不通, 开发电脑用的 windows.
    newaccount
        4
    newaccount  
       57 天前
    @abstime 代码不变,压缩包的文件名用 UTF8 编码,包含中文试试
    cheng6563
        5
    cheng6563  
       57 天前
    打 7z 包吧
    jov1
        6
    jov1  
       57 天前
    之前用的 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  
       57 天前
    https://cloud.tencent.com/developer/article/1130020

    换解压缩工具吧,看来 hutool 的 ziputil 在处理跨平台压缩文件中含中文的情况时就是有这个毛病
    albertofwb
        8
    albertofwb  
       56 天前
    集成 7z 使用命令行解压缩,很靠谱的
    dt201909
        9
    dt201909  
       56 天前
    考虑下前端解压不?一个可以减轻服务器压力,另一个可以及时发现是否 zip 包有问题。
    阿里云好像支持表单批量上传文件的,太久没看不记得了。
    PDF 压缩率似乎也不怎么样,因此不影响速度。
    vZexc0m
        10
    vZexc0m  
       56 天前
    为什么要在自己服务端进行压缩。这样太耗费资源了。我记得 OSS 有压缩功能。
    wnpllrzodiac
        11
    wnpllrzodiac  
       56 天前
    为啥要用 7zip 这个非标的东西。以后坑很多啊。全套都要用 7zip 而不能用标准 zip 算法。
    iseki
        12
    iseki  
       56 天前 via Android
    @wnpllrzodiac 7Z 格式怎么就非标了,主要是 Zip 格式太老了,字符编码都没统一,确实风险有点大。
    abstime
        13
    abstime  
    OP
       56 天前
    @cowcomic 使用链接中的方法, windows, mac 的压缩包都可以正常解压, 谢谢
    abstime
        14
    abstime  
    OP
       56 天前
    @vZexc0m 解压完后就删除了. 如果上传 oss 的话, 压缩包或直接文件得到一批链接, 不知道怎么和物料关联了, 这里压缩包中所有文件都是按物料编码命名的, 所以可以上传 oss 后拿到链接立即和物料关联. 也有物料单个去维护的功能, 但实际上都是不怎么维护, 一维护就是一大批所以遇到了这个问题.
    abstime
        15
    abstime  
    OP
       56 天前
    @albertofwb 没想过这么搞, 研究下
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2965 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 11:12 · PVG 19:12 · LAX 03:12 · JFK 06:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.