繁体   English   中英

Java中Zip文件的高效Stream

[英]Efficient Stream of Zip Files in Java

问题

在我的服务中,用户可以下载非常大的(5+ GB)数据包作为 zip 文件。 当前实现定位数据 package 中的所有文件,创建新的 zip 文件,使用文件副本填充 zip 文件,然后将其流式传输给用户。

这不适用于较大的数据包,我正在尝试找到一种方法来提高此过程的效率。 我在下面有一个建议的解决方案,但我没有提供内容的经验,并且希望对 go 的最佳方式有专业的见解。

尝试的解决方案

我认为最好的方法是不要将实际字节复制到 zip 文件中。 相反,创建符号链接的 zip 文件,然后在流式传输内容时复制字节。 我在传输过程中将字节实际复制到 zip 时遇到了问题,我不知道这是否可行。

最终解决方案

我将下面 Alexey Ragozin 接受的答案实现到SpeedBagIt中,这是一个用于有效流式传输符合BagIt规范的 zip 文件的库。

可以直接通过HTTP连接stream大zip文件。

java.util.zip.ZipOutputStream允许将 zip 数据直接存储到 ZF7B44CFAFD5C52223D7B4981 中间存储。

以下是将文件链接集合写入 stream 作为 zip 存档的片段。

对于 stream 5GiB 的原因,您可能需要调整 servlet 容器的超时和线程池。

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipStreamer {

    public void streamZip(OutputStream os, Iterable<FileLink> entries) throws IOException {
        ZipOutputStream zos = new ZipOutputStream(os);
        for(FileLink e: entries) {

            ZipEntry entry = new ZipEntry(e.getName());
            File file = e.getFile();
            entry.setTime(file.lastModified());
            zos.putNextEntry(entry);
            if (file.isFile()) {
                copyBytes(zos, new FileInputStream(file));
            }
            zos.closeEntry();
        }
        zos.close();
    }

    private static void copyBytes(OutputStream dest, InputStream source) {
        // copy data between streams
    }

    public interface FileLink {

        public String getName();

        public File getFile();
    }
}

暂无
暂无

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

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