1

I'm working with ZipArchive and it's mostly working, the one issue I am seeing is that when the file downloads I cannot open it with windows default archive routines. If I click the zip file and extract all I receive an error message that says there are no entries to extract. Anyone know why this is happening? For what it is worth, I can open the same file with 7zip and extract the file just fine.

    public virtual ActionResult GetZip()
    {
        var summary = GetBytes();
        var response = new MemoryStream();
        using (var stream = new MemoryStream())
        {
            using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
            {
                var entry = archive.CreateEntry("myfiletozip" + fileExt);

                using (var writer = new BinaryWriter(entry.Open()))
                {
                    writer.Write(summary, 0, summary.Length);
                }
                stream.Seek(0, SeekOrigin.Begin);
                stream.CopyTo(response);
            }
        }

        response.Seek(0, SeekOrigin.Begin);

        return this.File(response, MediaTypeNames.Application.Zip, "myzipfilename.zip");
    }

UPDATE:

Found this SO Answer and modified my source and it is working.... and I still don't know why.

        byte[] response;
        using (var stream = new MemoryStream())
        {
            using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
            {
                var entry = archive.CreateEntry("myfiletozip" + fileExt, CompressionLevel.Optimal);
                using (var entryStream = entry.Open())
                using (var fileToCompressStream = new MemoryStream(summary))
                {
                    fileToCompressStream.CopyTo(entryStream);
                }
            }
            response = stream.ToArray();
        }
Community
  • 1
  • 1
John Babb
  • 931
  • 10
  • 19
  • 1
    What does `this.File(...)` do? – Dawnkeeper Feb 20 '17 at 16:30
  • I believe that the issue was that I didn't explicitly dispose of the entry.Open() in the second example / update if added another using statement for the entry and this seemed to give me the correct behavior. – John Babb Feb 21 '17 at 18:50

1 Answers1

0

ZipArchive add some additional info(eg.checksum) to the stream when it is disposed,so you should not seek the stream or use it before ZipArchive object is disposed.

public virtual ActionResult GetZip()
{
    var summary = GetBytes();
    var response = new MemoryStream();
    using (var stream = new MemoryStream())
    {
        using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
        {
            var entry = archive.CreateEntry("myfiletozip" + fileExt);

            using (var writer = new BinaryWriter(entry.Open()))
            {
                writer.Write(summary, 0, summary.Length);
            }
        }
        //Use stream after archive is disposed
        stream.Seek(0, SeekOrigin.Begin);
        stream.CopyTo(response);
    }

    response.Seek(0, SeekOrigin.Begin);

    return this.File(response, MediaTypeNames.Application.Zip, "myzipfilename.zip");
}