繁体   English   中英

创建zip文件而不写入磁盘

[英]create zip file without writing to disk

我正在使用Springboot应用程序,当用户下载一些报告时,该应用程序必须将zip文件返回到前端。 我想创建一个zip文件而不将zip文件或原始文件写入磁盘。

我要压缩的目录包含其他目录,其中包含实际文件。 例如,dir1内部有subDir1和subDir2,subDir1将具有两个文件subDir1File1.pdf和subDir1File2.pdf。 subDir2也将在其中包含文件。

通过在磁盘上创建物理文件,我可以轻松地做到这一点。 但是,我觉得返回这些文件而不写入磁盘会更加优雅。

如果范围是要写入内存,则可以使用ByteArrayOutputStream 本质上,zip文件将完全包含在内存中,因此请确保不要冒险一次发出太多请求,并且文件大小应合理! 否则,这种方法可能会适得其反!

您可以使用以下代码段:

public static byte[] zip(final String str) throws IOException {

        if (StringUtils.isEmpty(str)) {
            throw new IllegalArgumentException("Cannot zip null or empty string");
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (GZIPOutputStream gos = new GZIPOutputStream(bos)) {
            gos.write(str.getBytes(StandardCharsets.UTF_8));
        }
        return bos.toByteArray();

    }

但是,正如另一个答案所述,请确保将所有内容都加载到Java内存中,以确保程序不会冒太大风险。

请注意,您应该尽可能流式传输。 就您而言,您可以将数据写入https://docs.oracle.com/javase/8/docs/api/index.html?java/util/zip/ZipOutputStream.html

此方法的唯一缺点是:客户端将无法显示下载状态栏,因为服务器将无法发送“ Content-length”标头。 这是因为ZIP文件的大小只有在生成后才能知道,但是服务器需要先发送标头。 因此-没有临时的zip文件-事先没有文件大小。

您还在谈论子目录。 在处理ZIP流时,这只是一个命名问题。 每个zip项目都需要这样命名:“ directory / directory2 / file.txt”。 解压缩时将产生子目录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM