使用System.IO.MemoryStream处理相对较大的zip存档

问题描述

我是System.IO流的新手,因此不确定我何时以及如何使用不同的流。

让我解释一下我的用例:

当前,我有一个具有FileStream安装的MS SQL数据库,其中存储了文件的FileNameByte[]Section。即

public partial class MyFiles {
    public int Id { get; set; }
    public int Section { get; set; } 
    public string FileName { get; set; }
    public byte[] Data { get; set; }
}

在某个时候,我希望能够下载属于特定部分的所有文件。因此,我想:

  • 查询特定于部分的文件
  • 写入ZipArchive
  • 将压缩文件作为FileContentResult

我决定使用MemoryStream来实现此目的,因为从我不必在服务器上使用文件系统的意义上来说,它是快速便捷的。该实现如下所示:

MemoryStream stream;
using (stream = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(stream,ZipArchiveMode.Create))
    {

        foreach (MyFiles file in fetchedFiles)
        {
            var fileEntry = zipArchive.CreateEntry(file.FileName);
            using (var entryStream = fileEntry.Open())
            {
                entryStream.Write(file.Data,file.Data.Length);
            }
        }
    }
}
return new SuccessResult<MemoryStream>(stream);

一切正常,我可以成功获取压缩文件。

但是,现在我开始怀疑此实现,因为这可能最终会处理合并在一起的文件,总计512MB-1GB。

该服务器功能强大,但是显然我不想在此过程中消耗所有内存。

我朝MemoryStream的方向走错了吗?理想情况下,我应该考虑其他事情吗?

解决方法

要考虑的另一件事是,您实际上在内存中有两次文件-一次在fetchedFiles中,然后又在zip文件中。

理想情况下,您需要将文件从数据库流式传输到输出流,或者实际上是zip文件。

不是获取所有文件,然后将它们添加到zip中,而是打开zip文件,然后将每个文件流式传输到zip文件中。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...