【问题标题】:creating a zip file from an object directly without disk IO直接从对象创建 zip 文件,无需磁盘 IO
【发布时间】:2015-02-13 11:47:19
【问题描述】:

我正在编写一个 REST API,它将接收一个 JSON 请求对象。请求对象必须被序列化为 JSON 格式的文件;该文件必须压缩成 zip 文件,并且 ZIP 文件必须发布到另一个服务,为此我必须反序列化 ZIP 文件。这一切都是因为我必须调用的服务希望我将数据作为 ZIP 文件发布。我想看看我是否可以避免磁盘 IO。有没有办法直接将对象转换为表示内存中 ZIP 内容的字节数组,而不是上述所有步骤?

注意:我更喜欢使用 .net 框架库(相对于外部库)来完成此操作

【问题讨论】:

  • 如果可以按照您的要求在不使用 IO 的情况下完成此操作,我将非常感兴趣
  • 使用内置的 ZipArchive 更新了答案。
  • 嘿@Aadith,您发现任何有用的答案吗?如果是这样,请给作者一些荣誉并将其标记为已接受!谢谢。
  • 当然@Jorge .. 感谢您的解决方案并为所需解决方案铺平了道路
  • 没问题!我很高兴你最终找到了方法:-)

标签: c# zip in-memory


【解决方案1】:

是的,可以完全在内存中创建一个 zip 文件,这里是一个使用 SharpZip 库的示例(更新:最后添加了一个使用 ZipArchive 的示例): p>

public static void Main()
{
    var fileContent = Encoding.UTF8.GetBytes(
        @"{
            ""fruit"":""apple"",
            ""taste"":""yummy""
          }"
        );


    var zipStream = new MemoryStream();
    var zip = new ZipOutputStream(zipStream);

    AddEntry("file0.json", fileContent, zip); //first file
    AddEntry("file1.json", fileContent, zip); //second file (with same content)

    zip.Close();

    //only for testing to see if the zip file is valid!
    File.WriteAllBytes("test.zip", zipStream.ToArray());
}

private static void AddEntry(string fileName, byte[] fileContent, ZipOutputStream zip)
{
    var zipEntry = new ZipEntry(fileName) {DateTime = DateTime.Now, Size = fileContent.Length};
    zip.PutNextEntry(zipEntry);
    zip.Write(fileContent, 0, fileContent.Length);
    zip.CloseEntry();
}

您可以使用Nuget命令PM> Install-Package SharpZipLib获取SharpZip

更新:

注意:我更喜欢使用 .net 框架库(相对于外部库)来完成此操作

这是一个使用来自System.IO.Compression.Dll 的内置ZipArchive 的示例

public static void Main()
{
    var fileContent = Encoding.UTF8.GetBytes(
        @"{
            ""fruit"":""apple"",
            ""taste"":""yummy""
          }"
        );

    var zipContent = new MemoryStream();
    var archive = new ZipArchive(zipContent, ZipArchiveMode.Create);

    AddEntry("file1.json",fileContent,archive);
    AddEntry("file2.json",fileContent,archive); //second file (same content)

    archive.Dispose();

    File.WriteAllBytes("testa.zip",zipContent.ToArray());
}


private static void AddEntry(string fileName, byte[] fileContent,ZipArchive archive)
{
    var entry = archive.CreateEntry(fileName);
    using (var stream = entry.Open())
        stream.Write(fileContent, 0, fileContent.Length);

}

【讨论】:

  • 你不能只使用 System.IO.Compression.ZipArchive 而不是安装 NuGet 吗?
  • @Jorge,是的,有可能,这是基于个人喜好,我会更新答案。
  • 感谢@user3473830,您修改后的解决方案符合我的要求
  • 如何修改它以在 zip 存档中创建一个文件夹?
  • @user3473830 感谢 ZipArchive 版本的代码。尝试对依赖于 ZipArchive 的组件进行单元测试。我正在搜索解决方案大约 2 小时,但直到看到您的答案才找到。
【解决方案2】:

您可以将GZipStream 类与MemoryStream 一起使用。

一个简单的例子:

using System.IO;
using System.IO.Compression;

//Put JSON into a MemoryStream
var theJson = "Your JSON Here";
var jsonStream = new MemoryStream();
var jsonStreamWriter = new StreamWriter(jsonStream);
jsonStreamWriter.Write(theJson);
jsonStreamWriter.Flush();

//Reset stream so it points to the beginning of the JSON
jsonStream.Seek(0, System.IO.SeekOrigin.Begin);

//Create stream to hold your zipped JSON
var zippedStream = new MemoryStream();

//Zip JSON and put it in zippedStream via compressionStream.
var compressionStream = new GZipStream(zippedStream, CompressionLevel.Optimal);
jsonStream.CopyTo(compressionStream);

//Reset zipped stream to point at the beginning of data
zippedStream.Seek(0, SeekOrigin.Begin);

//Get ByteArray with zipped JSON
var zippedJsonBytes = zippedStream.ToArray();

【讨论】:

  • 当我尝试这个时,我得到一个 zippedJsonBytes 的 0 大小数组。看起来某处有一个小问题..你能帮帮我吗
  • 如果我没记错的话,OP需要创建一个Zip容器,恐怕建议的方案只用Gzip算法压缩数据,不符合Zip容器格式。
  • 谢谢@user3473830 ..那将是我的另一个问题..zip和gzip有什么区别?
  • @Aadith,如果您需要的是整个 zip 存档(而不是压缩数据),那么您可以使用 ZipArchive 类,如下所示。 MSDN 中有一个使用 FileStreams 的示例,但您也可以像我的示例一样使用 MemoryStreams。
【解决方案3】:

您应该尝试将ZipArchive Class 流式传输到MemoryStream Class

【讨论】:

    【解决方案4】:

    是的。您可以将其作为二进制流返回。根据语言,您可以使用特殊库。您还需要客户端上的库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-16
      相关资源
      最近更新 更多