Cannot open generated zip file

旧城冷巷雨未停 提交于 2021-01-29 02:09:15

问题


I've followed several articles to create a zip file using java ZipOutputStream class. The zip is created but I cannot open it. On my Mac I'm receiving this message when I open it with the unzip command :

End-of-central-directory signature not found. Either this file is not a zipfile, or it constitutes one disk of a multi-part archive. In the latter case the central directory and zipfile comment will be found on the last disk(s) of this archive.

unzip: cannot find zipfile directory in one of /Users/xxxx/Downloads/iad.zip or
/Users/xxxx/Downloads/iad.zip.zip, and cannot find /Users/xxxx/Downloads/iad.zip.ZIP, period.

My java class :

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static java.util.Arrays.stream;

@Slf4j
@UtilityClass
public class ZipCreator {

    public byte[] compressAll(String... files) throws IOException {

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             ZipOutputStream zipOut = new ZipOutputStream(baos)) {

            stream(files)
                    .forEach(file -> addToZip(zipOut, file));

            return baos.toByteArray();
        }
    }

    private static void addToZip(ZipOutputStream zipOut, String file) {
        File fileToZip = new File(file);
        try (FileInputStream fis = new FileInputStream(fileToZip.getCanonicalFile())) {
            zipOut.putNextEntry(new ZipEntry(fileToZip.getName()));

            byte[] bytes = new byte[1024];
            int length;
            while ((length = fis.read(bytes)) >= 0) {
                zipOut.write(bytes, 0, length);
            }
        } catch (IOException e) {
            log.error("Error when adding file {} to zip", file, e);
        }
    }
}

Doas anyone have an idea to get this zip open ?


回答1:


You forgot to call closeEntry(). And you should call close() for ZipOutputStream before baos.toByteArray():

public static byte[] compressAll(String... files) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try (ZipOutputStream zipOut = new ZipOutputStream(baos)) {
        stream(files).forEach(file -> addToZip(zipOut, file));
    }
    return baos.toByteArray();
}

private static void addToZip(ZipOutputStream zipOut, String file) {
    File fileToZip = new File(file);
    try (FileInputStream fis = new FileInputStream(fileToZip.getCanonicalFile())) {
        zipOut.putNextEntry(new ZipEntry(fileToZip.getName()));

        byte[] bytes = new byte[1024];
        int length;
        while ((length = fis.read(bytes)) >= 0) {
            zipOut.write(bytes, 0, length);
        }

        zipOut.closeEntry();
    } catch (IOException e) {
        log.error("Error when adding file {} to zip", file, e);
    }
}

For ByteArrayOutputStream you must close ZipOutputStream before retrieve byte array from ByteArrayOutputStream. For FileOutputStream is the same. You must close ZipOutputStream before closing FileOutputStream. Note that the close methods of resources are called in the opposite order of their creation.

public static void compressAll(String... files) throws IOException {
    try (FileOutputStream fos = new FileOutputStream("test.zip");
         ZipOutputStream zipOut = new ZipOutputStream(fos)) {
        stream(files).forEach(file -> addToZip(zipOut, file));
    }
}


来源:https://stackoverflow.com/questions/60745803/cannot-open-generated-zip-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!