Java中高效的Zip文件流

3

问题

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

随着数据包越来越大,这种方法的可扩展性不够好,我正在尝试找到一种提高此过程效率的方法。下面是我的解决方案,但我没有提供内容的经验,希望专业人士能就最佳解决方案提供意见。

尝试的解决方案

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

最终解决方案

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


https://www.java67.com/2016/12/how-to-create-zip-file-in-java-zipentry-example.html - undefined
1个回答

5

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

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

以下是将文件链接集合写入流作为ZIP档案的代码片段。

当然,要流式传输5 GiB的文件,您可能需要调整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();
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接