java

Java原生库解压Zip流报错malformed input off : 52, length

我的报错情况是:压缩包中有一个文件,文件名是“新建文本文档.txt”

报错信息为

java.lang.IllegalArgumentException: malformed input off : 52, length : 1
从上面的报错信息,可看到UTF8 等编码的相关信息

解压代码为

package com.patac.devPortalBackend.utils;

import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Zip {
    public static void decompress(MultipartFile zipFile, String outputDirectory) throws IOException {

        byte[] buffer = new byte[1024];

        // 创建输出目录
        Path outputPath = Paths.get(outputDirectory);
        if (!Files.exists(outputPath)) {
            Files.createDirectories(outputPath);
        }

        try (
                InputStream inputStream = zipFile.getInputStream();
                ZipInputStream zis = new ZipInputStream(inputStream)
        ) {
            ZipEntry entry = zis.getNextEntry();

            while (entry != null) {
                Path entryOutputPath = outputPath.resolve(entry.getName());
                if (!entry.getName().contains("__MACOSX")) {
                    if (entry.isDirectory()) {
                        // 如果条目是一个目录,则创建相应的输出目录
                        Files.createDirectories(entryOutputPath);
                    } else {
                        // 否则,将条目内容写入文件
                        try (OutputStream os = Files.newOutputStream(entryOutputPath)) {
                            int len;
                            while ((len = zis.read(buffer)) > 0) {
                                os.write(buffer, 0, len);
                            }
                        }
                    }
                }
                zis.closeEntry();
 // 这里是报错的行
                entry = zis.getNextEntry();
            }
        }
    }
}

报错原因

Jdk原生Zip流,会因为文件或文件夹名字的编码问题,导致报MALFORMED错

解决方案

使用apach-commons-compress可获得更好的兼容性

pom中引入如下依赖

<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-compress</artifactId>
			<version>1.18</version>
		</dependency>

代码做如下更改

package com.patac.devPortalBackend.utils;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Zip {
    public static void decompress(MultipartFile zipFile, String outputDirectory) throws IOException {

        byte[] buffer = new byte[1024];

        // 创建输出目录
        Path outputPath = Paths.get(outputDirectory);
        if (!Files.exists(outputPath)) {
            Files.createDirectories(outputPath);
        }

        try (
                InputStream inputStream = zipFile.getInputStream();
                ZipArchiveInputStream zis = new ZipArchiveInputStream(inputStream);
//                ZipInputStream zis = new ZipInputStream(inputStream)
        ) {
            ArchiveEntry entry = zis.getNextEntry();

            while (entry != null) {
                Path entryOutputPath = outputPath.resolve(entry.getName());
                System.out.println("entry name------"+entry.getName());
                if (!entry.getName().contains("__MACOSX")) {
                    if (entry.isDirectory()) {
                        // 如果条目是一个目录,则创建相应的输出目录
                        Files.createDirectories(entryOutputPath);
                    } else {
                        // 否则,将条目内容写入文件
                        try (OutputStream os = Files.newOutputStream(entryOutputPath)) {
                            int len;
                            while ((len = zis.read(buffer)) > 0) {
                                os.write(buffer, 0, len);
                            }
                        }
                    }
                }
                entry = zis.getNextEntry();
            }
        }
    }
}

留言

您的邮箱地址不会被公开。 必填项已用 * 标注

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。