首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >流压缩文件: java.util.zip.ZipException:无效的条目大小(预期为0,但实际为419字节)

流压缩文件: java.util.zip.ZipException:无效的条目大小(预期为0,但实际为419字节)
EN

Stack Overflow用户
提问于 2021-03-01 00:55:52
回答 1查看 493关注 0票数 1

我有一个web服务来处理ZIP文件的内容,这些内容是我从网络源接收到的,然后动态地流回网络目标。这对于我的大约60%的测试文件非常有效,但是其中40%无法处理,因为zipEntry.getSize()返回-1作为所有压缩条目的文件大小。

下面您可以看到两个java测试,它们将内容从源zip流式传输到目标zip。第一个命令接受任何InputStream作为源(这正是我需要的,因为我直接从网络获取数据),并且无法处理大小未知(-1)的zip条目。

第二个测试知道如何处理未知(-1)大小的条目,但只能处理来自本地文件的流(这不是我需要的-这里只是为了证明有问题的压缩文件没有损坏)。

网上有很多处理本地zip文件的例子--但处理网络流的例子很少,这就是为什么我很难找到解决方案的原因。

第一个示例抛出的错误是Stream Zip files: java.util.zip.ZipException: invalid entry size (expected 0 but got 419 bytes)

下面是我的代码:

代码语言:javascript
运行
复制
package de.ftk.threemf.mesh;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Date;
import java.util.Enumeration;
import java.util.zip.*;

@Slf4j
public class ZipStreamTests {

    @Test
    public void generalizedStreamZipTest() throws IOException {
        Path path = Path.of("testdata/brokenzip/trex.3mf");
        InputStream in = Files.newInputStream(path);
        OutputStream out = Files.newOutputStream(Path.of("testoutput/ziptest.3mf"));

        ZipInputStream zipInputStream = new ZipInputStream(in);
        ZipEntry zipEntry;

        CheckedOutputStream checkedOutputStream = new CheckedOutputStream(out, new Adler32());
        ZipOutputStream zipOutputStream = new ZipOutputStream(checkedOutputStream);

        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            log.info("zip file contains: {} modified on {}", zipEntry.getName(), new Date(zipEntry.getTime()));
            zipOutputStream.putNextEntry(zipEntry);
            log.info("expecting " + zipEntry.getSize() + " bytes");
            IOUtils.copy(zipInputStream, zipOutputStream);
            zipOutputStream.closeEntry();
            zipInputStream.closeEntry();
        }
        zipInputStream.close();
        zipOutputStream.finish();
        zipOutputStream.close();
        in.close();
        out.close();
    }

    @Test
    public void fileStreamZipTest() throws IOException {
        ZipFile zipFile = new ZipFile("testdata/brokenzip/trex.3mf");
        final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("testoutput/ziptest.3mf"));
        for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
            ZipEntry entryIn = e.nextElement();
            log.info("zip file contains: {} modified on {}", entryIn.getName(), new Date(entryIn.getTime()));
            ZipEntry zipEntry = new ZipEntry(entryIn.getName());
            log.info("expecting " + zipEntry.getSize() + " bytes");
            zos.putNextEntry(zipEntry);
            InputStream is = zipFile.getInputStream(entryIn);
            byte[] buf = new byte[1024];
            int len;
            while ((len = (is.read(buf))) > 0) {
                zos.write(buf);
            }
            zos.closeEntry();
        }
        zos.close();
    }

}

提示:3MF文件是包含3D模型的ZIP文件。

EN

回答 1

Stack Overflow用户

发布于 2021-05-15 19:42:12

这与ZIP64子格式https://www.ibm.com/support/pages/zip-file-unreadable-cause-javautilzipzipexception-invalid-entry-size相关

较新的java7和java8版本已修复此问题- jdk-1.8.0_91不正常,openjdk-1.8.0.212.b04正常。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66411556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档