C# 直接从对象创建zip文件而不使用磁盘IO

C# 直接从对象创建zip文件而不使用磁盘IO,c#,zip,in-memory,C#,Zip,In Memory,我正在编写一个RESTAPI,它将接收一个JSON请求对象。请求对象必须序列化为JSON格式的文件;该文件必须压缩成zip文件,并且必须将zip文件发布到另一个服务,为此,我必须对zip文件进行反序列化。所有这些都是因为我必须调用的服务要求我将数据作为ZIP文件发布。我正在试着看看是否可以避免磁盘IO。是否有一种方法可以直接将对象转换为表示内存中ZIP内容的字节数组,而不是上述所有步骤 注意:我更喜欢使用.net framework库(相对于外部库)来实现这一点。您可以将其作为二进制流返回。根据

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


注意:我更喜欢使用.net framework库(相对于外部库)来实现这一点。您可以将其作为二进制流返回。根据语言的不同,您可以使用特殊的库。您还需要客户端上的库。

您可以将该类与一起使用

一个简单的例子:

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();

您应该尝试将数据流传输到

是的,可以完全在内存中创建zip文件,下面是一个使用
SharpZip
库的示例(更新:在末尾添加了一个使用
ZipArchive
的示例):

您可以使用Nuget命令
PM>安装软件包SharpZipLib

更新:

注意:我更喜欢使用.NETFramework库来实现这一点(与外部库相比)

下面是一个使用
System.IO.Compression.Dll

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);

}

我非常感兴趣的是,当你使用内置ZipArchive询问答案时,如果不使用IO就可以实现这一点。嘿@Aadith,你觉得这些答案有用吗?如果是这样,请给作者一些荣誉,并标记为接受一个!谢谢,当然可以。。感谢您的解决方案,并为所需解决方案铺平道路。没问题!我很高兴您最终找到了方法:-)当我尝试这个方法时,我得到了一个0大小的zippedJsonBytes数组。看起来有个小问题……你能帮我解决吗如果我没弄错的话,OP需要创建一个
Zip
容器,恐怕提议的解决方案只使用Gzip算法压缩数据,不符合Zip容器格式。谢谢@user3473830..这将是我的另一个问题..Zip和Gzip之间有什么区别?@Aadith,如果您需要的是一个完整的Zip存档(与压缩数据相反)然后,您可以按照下面的建议使用ZipArchive类。MSDN中有一个使用FileStreams的示例,但您也可以像我的示例一样使用MemoryStream。@Aadith,难道您不能使用System.IO.Compression.ZipArchive而不是安装NuGet吗?@Jorge,是的,这是可能的,这是基于个人偏好,我将更新答案。谢谢@user3473830您修改后的解决方案符合我的要求如何修改此解决方案以在zip存档中创建文件夹?@user3473830感谢ZipArchive版本的代码。正在尝试对依赖于ZipArchive的组件进行单元测试。这是大约2个小时,我正在寻找解决方案,但无法找到,直到看到你的答案。
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);

}