文件上传后解压缩的问题

21 天前
 abstime

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

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

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

换解压缩工具吧,看来 hutool 的 ziputil 在处理跨平台压缩文件中含中文的情况时就是有这个毛病
albertofwb
21 天前
集成 7z 使用命令行解压缩,很靠谱的
dt201909
20 天前
考虑下前端解压不?一个可以减轻服务器压力,另一个可以及时发现是否 zip 包有问题。
阿里云好像支持表单批量上传文件的,太久没看不记得了。
PDF 压缩率似乎也不怎么样,因此不影响速度。
vZexc0m
20 天前
为什么要在自己服务端进行压缩。这样太耗费资源了。我记得 OSS 有压缩功能。
wnpllrzodiac
20 天前
为啥要用 7zip 这个非标的东西。以后坑很多啊。全套都要用 7zip 而不能用标准 zip 算法。
iseki
20 天前
@wnpllrzodiac 7Z 格式怎么就非标了,主要是 Zip 格式太老了,字符编码都没统一,确实风险有点大。
abstime
20 天前
@cowcomic 使用链接中的方法, windows, mac 的压缩包都可以正常解压, 谢谢
abstime
20 天前
@vZexc0m 解压完后就删除了. 如果上传 oss 的话, 压缩包或直接文件得到一批链接, 不知道怎么和物料关联了, 这里压缩包中所有文件都是按物料编码命名的, 所以可以上传 oss 后拿到链接立即和物料关联. 也有物料单个去维护的功能, 但实际上都是不怎么维护, 一维护就是一大批所以遇到了这个问题.
abstime
20 天前
@albertofwb 没想过这么搞, 研究下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1085347

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX