Create zip file from object directly without disk IO

I am writing a REST API that will accept a JSON request object. The request object must be serialized to a JSON file; the file must be compressed into a zip file and the ZIP file must be sent to another service, for which I will have to deserialize the ZIP file. This is all because the service I have to call expects me to send the data as a ZIP file. I am trying to see if I can avoid disk IO. Is there a way to directly convert an object to a byte array representing the zip content in memory instead of all of the above steps?

Note. I would rather accomplish this using the .net framework libraries (as opposed to external libraries).

+3


source to share


4 answers


Yes, it is possible to create a zip file entirely in memory, here is an example using SharpZip

Library ( Update: sample using ZipArchive

appended at the end
):

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

      

You can get SharpZip

with Nuget commandPM> Install-Package SharpZipLib

Update:



Note. I would rather accomplish this using the .net framework libraries (as opposed to external libraries).

Here is an example using the inline ZipArchive

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

}

      

+6


source


You can use the GZipStream class along with a MemoryStream .

Quick example:



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

      

+3


source


You should try the ZipArchive class to go to the MemoryStream Class

+2


source


Yes. You can return it as a binary stream. Depending on the language, you can use special libraries. You will also need libraries on the client.

0


source







All Articles