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

时间:2014-12-15 11:31:28

标签: c# zip in-memory

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

注意:我更喜欢使用.net框架库(与外部库相比)来实现这一目标

4 个答案:

答案 0 :(得分:6)

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

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命令SharpZip

获取PM> Install-Package SharpZipLib

<强>更新

  

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

以下是使用ZipArchive

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

}

答案 1 :(得分:3)

您可以将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();

答案 2 :(得分:2)

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

答案 3 :(得分:0)

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