java - Java 中的高效 Zip 文件流

标签 java performance download streaming

问题

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

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

尝试的解决方案

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

最终解决方案

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

最佳答案

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

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

下面是将文件链接集合作为 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();
    }
}

关于java - Java 中的高效 Zip 文件流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58309057/

相关文章:

java - 在多线程环境下如何发现ThreadPoolTask​​Executor已满?

performance - Haskell 中的素筛

.net - 如何计算一段 .NET 代码的 CPU 使用率?

php - 使用浏览器提示下载文件

java - jaxb2-maven-plugin 与 JUnit4 的集成

java - 登录基于 php 的网站并抓取数据 - 问题

mysql - 单字段数组或多行

javascript - 文件未下载 blob 链接

linux - 使用 Perl 在 Unix/Linux 环境中下载和处理文件的管道

java - 将主类值存储在子类中作为数组