Invalid zip file after creating it with System.IO.Compression

后端 未结 4 1707
死守一世寂寞
死守一世寂寞 2021-02-12 15:58

I\'m trying to create a zip file that contains one or more files.
I\'m using the .NET framework 4.5 and more specifically System.IO.Compression namespace.
The objectiv

相关标签:
4条回答
  • 2021-02-12 16:02

    When I added a wrong name for the entry as in the example

    var fileToZip = "/abc.txt";
    ZipArchiveEntry zipFileEntry = zipArchive.CreateEntry(fileToZip);
    

    I got the same error. After correcting the file name, it is ok now.

    0 讨论(0)
  • 2021-02-12 16:04

    Try changing

    using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create, false))
    

    to

    using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
    

    In this usage, the archive is forced to write to the stream when it is closed. However, if the leaveOpen argument of the constructor is set to false, it will close the underlying stream too.

    0 讨论(0)
  • 2021-02-12 16:08

    Just return the stream...

    private ActionResult CreateZip(IEnumerable files)
    {
        if (files.Any())
        {
            MemoryStream zipStream = new MemoryStream();
            using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create, false))
            {
                foreach (var f in files)
                {
                   var entry = archive.CreateEntry(f.FileDownloadName, CompressionLevel.Fastest);
                   using (var entryStream = entry.Open())
                   {
                       entryStream.Write(f.FileContents, 0, f.FileContents.Length);
                       entryStream.Close();
                   }
               }
    
            }
    
            zipStream.Position = 0;
            return File(zipStream, MediaTypeNames.Application.Zip, "horta.zip");
        }
    
        return new EmptyResult();
    }
    0 讨论(0)
  • 2021-02-12 16:14

    You need to get the MemoryStream buffer via ToArray after the ZipArchive object gets disposed. Otherwise you end up with corrupted archive.

    And please note that I have changed the parameters of ZipArchive constructor to keep it open when adding entries.

    There is some checksumming going on when the ZipArchive is beeing disposed so if you read the MemoryStream before, it is still incomplete.

        private FileResult CreateZip(IEnumerable<FileContentResult> files)
        {
            byte[] retVal = null;
    
            if (files.Any())
            {
                using (MemoryStream zipStream = new MemoryStream())
                {
                    using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
                    {
                        foreach (var f in files)
                        {
                            var entry = archive.CreateEntry(f.FileDownloadName, CompressionLevel.Fastest);
                            using (BinaryWriter writer = new BinaryWriter(entry.Open()))
                            {                                   
                                writer.Write(f.FileContents, 0, f.FileContents.Length);
                                writer.Close();
                            }
                        }
    
                        zipStream.Position = 0;
                    }
                    retVal = zipStream.ToArray();
                }
            }
    
            return File(retVal, MediaTypeNames.Application.Zip, "horta.zip");
        }
    
    0 讨论(0)
提交回复
热议问题