我有一个用这种方法压缩的目录:
public byte[] archiveDir(File dir) {
try(ByteArrayOutputStream bos = new ByteArrayOutputStream(); ZipOutputStream zout = new ZipOutputStream(bos)) {
zipSubDirectory("", dir, zout);
return bos.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void zipSubDirectory(String basePath, File dir, ZipOutputStream zout) throws IOException {
byte[] buffer = new byte[4096];
File[] files = dir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
String path = basePath + file.getName() + "/";
zout.putNextEntry(new ZipEntry(path));
zipSubDirectory(path, file, zout);
zout.closeEntry();
} else {
FileInputStream fin = new FileInputStream(file);
zout.putNextEntry(new ZipEntry(basePath + file.getName()));
int length;
while ((length = fin.read(buffer)) > 0) {
zout.write(buffer, 0, length);
}
zout.closeEntry();
fin.close();
}
}
}
然后我将字节写入servlet的输出流。但是当我收到zip文件时,它无法打开"文件格式错误"。如果我将压缩内容输出到FileOutputStream然后将文件内容发送到servlet的输出流,它可以正常工作。好吧,这将解决我的问题,但在这种情况下,我总是必须删除临时zip文件后,其内容被发送到servlet的outpu流。是否有可能只在内存中这样做。
答案 0 :(得分:4)
嗯,
zipSubDirectory(path, file, zout);
zout.closeEntry();
应该是:
zout.closeEntry();
zipSubDirectory(path, file, zout);
主要错误似乎是在调用 toByteArray之前未关闭/刷新。尝试资源有点狡猾。
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
try ((ZipOutputStream zout = new ZipOutputStream(bos)) {
zipSubDirectory("", dir, zout);
}
return bos.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}