将压缩目录输出到ByteArrayOutputStream

时间:2014-12-05 11:31:46

标签: java servlets file-io

我有一个用这种方法压缩的目录:

 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流。是否有可能只在内存中这样做。

1 个答案:

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