【问题标题】:Efficient Stream of Zip Files in JavaJava 中高效的 Zip 文件流
【发布时间】:2019-10-09 17:05:20
【问题描述】:

问题

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

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

尝试的解决方案

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

结束解决方案

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

【问题讨论】:

标签: java performance download streaming


【解决方案1】:

您可以通过 HTTP 连接直接流式传输大型 zip 文件。

java.util.zip.ZipOutputStream 允许将数据直接压缩到流中,无需中间存储。

下面是 sn-p 将文件链接集合写入流作为 zip 存档。

由于要流式传输 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();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-24
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    • 2022-06-26
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    相关资源
    最近更新 更多