ZipArchive with in memory data dotnet

86 views Asked by At

I am trying to create a Zip Archive in C# with data that is created in memory. However every time I try to finally save the archive to disk it is empty. Right now I am testing with one file but it will end up being a list of files that will get archived.

var data = new Data
{
    FirstName = "FirstName",
    LastName = "LastName"
};

var json = JsonConvert.SerializeObject(data, Formatting.Indented);
var bytes = Encoding.UTF8.GetBytes(json);
using var file = new MemoryStream(bytes);

using var archiveStream = new MemoryStream();
var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true);

var archiveEntry = archive.CreateEntry("data.json", CompressionLevel.Fastest);
using var entryStream = archiveEntry.Open();
file.CopyTo(entryStream);

using var fileStream = new FileStream("/Path/To/File/test.zip", FileMode.Create, FileAccess.Write);
archiveStream.CopyTo(fileStream);

What am I missing?

2

There are 2 answers

1
Schamal On BEST ANSWER

As mentioned in https://stackoverflow.com/a/17939367/14918126 the problem is that archiveStream needs to be disposed before you can use it. And you should set the position of the archiveStream to the start before copy it to the fileStream. Following solution should work:

        var data = new Data
        {
            FirstName = "FirstName",
            LastName = "LastName"
        };

        var json = JsonConvert.SerializeObject(data, Formatting.Indented);
        var bytes = Encoding.UTF8.GetBytes(json);
        using var file = new MemoryStream(bytes);

        using var archiveStream = new MemoryStream();
        var archive = new ZipArchive(archiveStream, ZipArchiveMode.Create, true);

        var archiveEntry = archive.CreateEntry("data.json", CompressionLevel.Fastest);
        using var entryStream = archiveEntry.Open();
        file.CopyTo(entryStream);
        archive.Dispose();

        using var fileStream = new FileStream("./test2.zip", FileMode.Create, FileAccess.Write);
        archiveStream.Seek(0, SeekOrigin.Begin);
        archiveStream.CopyTo(fileStream);
0
beautifulcoder On

You will need to go back to the beginning of the memory stream once you have written into it.

archiveStream.Seek(0, SeekOrigin.Begin);
archiveStream.CopyTo(fileStream);