Не удается открыть сгенерированный zip-файл - PullRequest
0 голосов
/ 18 марта 2020

Я следовал нескольким статьям, чтобы создать zip-файл с использованием класса java ZipOutputStream. Почтовый индекс создан, но я не могу его открыть. На моем Ma c я получаю это сообщение, когда открываю его командой unzip:

Подпись конца центрального каталога не найдена. Либо этот файл не является zip-файлом, либо он представляет собой один диск из многочастного архива. В последнем случае центральный каталог и комментарий к zipfile будут найдены на последнем диске (ах) этого архива.

unzip: не удается найти каталог zipfile в одном из /Users/xxxx/Downloads/iad.zip или
/Users/xxxx/Downloads/iad.zip.zip и не может найти / Users / xxxx / Downloads / iad.zip.ZIP, точка.

Мой java класс:

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);
        }
    }
}

У кого-нибудь есть идея открыть этот почтовый индекс?

1 Ответ

2 голосов
/ 18 марта 2020

Вы забыли позвонить closeEntry (). И вы должны вызвать close () для ZipOutputStream перед 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);
    }
}

Для ByteArrayOutputStream вы должны закрыть ZipOutputStream перед извлечением байтового массива из ByteArrayOutputStream. Для FileOutputStream то же самое. Вы должны закрыть ZipOutputStream перед закрытием FileOutputStream. Обратите внимание, что методы закрытия ресурсов вызываются в порядке, обратном их созданию.

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));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...