问题
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