Java: 一个 zip in a zip 变得不可读

Java: A zip in a zip becomes unreadable

对于一个项目,我需要创建一个包含两个 zip 文件的 zip。 我创建了一些方法来执行此操作,但是生成的 zip 文件不正确。

考虑以下测试class:

package nl.test;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.junit.Test;

public class ZipTest {

    @Test
    public void test() throws IOException {
        Path p = Paths.get("input.txt");
        try (BufferedWriter writer = Files.newBufferedWriter(p)) {
            writer.write("text to compress");
        }
        Path p1 = createZipFile("p.zip", p);
        createZipFile("p1.zip", p1);
    }

    private Path createZipFile(String zipName, Path p) {
        try {
            OutputStream fos = Files.newOutputStream(Paths.get(zipName));
            ZipOutputStream zos = new ZipOutputStream(fos);
            OutputStream bos = new BufferedOutputStream(zos);
            try (Writer writer = new OutputStreamWriter(bos)) {
                zos.putNextEntry(new ZipEntry(p.toString()));
                writer.write(new String(Files.readAllBytes(p)));
                writer.flush();
            }
            return Paths.get(zipName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

执行此操作时,文件 p1.zip 确实包含一个 p.zip,但是 p.zip 是不可读的。 有没有办法来解决这个问题? 或者还有另一种方法可以将 zip 放在 zip 中吗?

这里有一个更简单的方法:

  1. 右键单击要添加到 "p.zip"
  2. 中的文件
  3. 单击“添加到存档”并根据需要编辑设置
  4. 右键单击存在 p.zip 的文件夹中的任意位置,然后将鼠标悬停在新建和 select "Compressed Zipped Folder"
  5. 创建后,只需将 p.zip 拖到刚刚创建的压缩文件夹中即可。
  6. 瞧!

直到我发现这不起作用的原因,才使用 zip4j 解决了这个问题:

package nl.test;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.junit.Test;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

public class ZipTest2 {

    @Test
    public void test() throws IOException {
        Path p = Paths.get("input.txt");
        try (BufferedWriter writer = Files.newBufferedWriter(p)) {
            writer.write("text to compress");
        }
        Path p1 = createZipFile("p1.zip", p);
        createZipFile("p2.zip", p1);
    }

    private Path createZipFile(String compressedFile, Path inputPath) {
        try {
            ZipFile zipFile = new ZipFile(compressedFile);
            ZipParameters parameters = new ZipParameters();

            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_FASTEST);
            zipFile.addFile(inputPath.toFile(), parameters);

            return Paths.get(compressedFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

这在将生成的 zip 添加到另一个 zip 时有效。