5

I try to create a zip file in memory with c#, but the result is a zip file with corrupted files inside it. All file to zip are in a database. I store the bytes. The files are PDF. my code is the following

//[extract bytes and file name for every file]

using (var zipArchiveMemoryStream = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(zipArchiveMemoryStream,
                                           ZipArchiveMode.Create, true))
    {
        foreach (var file in fileData)
        {
            var zipEntry = zipArchive.CreateEntry(file.FileName);
            using (var entryStream = zipEntry.Open())
            {
                using (var tmpMemory = new MemoryStream(file.Bytes))
                {
                    tmpMemory.CopyTo(entryStream);
                };

            }
        }
    }
    zipArchiveMemoryStream.Position = 0;
    result = zipArchiveMemoryStream.GetBuffer();

//[download zip file]

Thanks in advance for your support

SOLUTION BY TONIGNO: the problem was that i use GetBuffer(); instead ToArray();

using (var zipArchiveMemoryStream = new MemoryStream())
        {
            using (var zipArchive = new ZipArchive(zipArchiveMemoryStream, ZipArchiveMode.Create, true))
            {
                foreach (var file in fileData)
                {
                    var zipEntry = zipArchive.CreateEntry(file.FileName);
                    using (var entryStream = zipEntry.Open())
                    {
                        using (var tmpMemory = new MemoryStream(file.Bytes))
                        {
                            tmpMemory.CopyTo(entryStream);
                        };

                    }
                }
            }

            zipArchiveMemoryStream.Seek(0, SeekOrigin.Begin);
            result = zipArchiveMemoryStream.ToArray();
        }

        return result;
Luca Dalsass
  • 63
  • 1
  • 1
  • 4

2 Answers2

5

Try to take a look to this: Creating a ZIP Archive in Memory Using System.IO.Compression. The solution is this:

using (var memoryStream = new MemoryStream())
{
   using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
   {
      var demoFile = archive.CreateEntry("foo.txt");

      using (var entryStream = demoFile.Open())
      using (var streamWriter = new StreamWriter(entryStream))
      {
         streamWriter.Write("Bar!");
      }
   }

   using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
   {
      memoryStream.Seek(0, SeekOrigin.Begin);
      memoryStream.CopyTo(fileStream);
   }
}

It explains how to create the zip archive in memory and contains a link to another useful article that explains the use of the leaveOpen argument to prevent the closing of the stream: ZipArchive creates invalid ZIP file that contains this solution:

using (MemoryStream zipStream = new MemoryStream())
{
    using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
    {
        var entry = zip.CreateEntry("test.txt");
        using (StreamWriter sw = new StreamWriter(entry.Open()))
        {
            sw.WriteLine(
            "Etiam eros nunc, hendrerit nec malesuada vitae, pretium at ligula.");
        }
    }

    var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(
    "test.zip",
    CreationCollisionOption.ReplaceExisting);

    zipStream.Position = 0;
    using (Stream s = await file.OpenStreamForWriteAsync())
    {
        zipStream.CopyTo(s);
    }
}

I hope it's helpful!

EDIT

Instead of zipArchiveMemoryStream.GetBuffer() use zipArchiveMemoryStream.ToArray()

Community
  • 1
  • 1
Tonigno
  • 94
  • 9
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Gerald Versluis Jul 10 '15 at 09:01
  • 1
    Ok, I'm sorry! Thank you for the advice! – Tonigno Jul 10 '15 at 09:07
  • No problem, take it as an advice! ;) – Gerald Versluis Jul 10 '15 at 09:08
  • i take another try but i have already read the linked articles. The difference in my case is that i do not have physical files but only the bytes. I can't save it on hard drive before to zip it. I'll let you know – Luca Dalsass Jul 10 '15 at 09:52
  • Ok, instead of `zipArchiveMemoryStream.GetBuffer()` try to use `zipArchiveMemoryStream.ToArray()` – Tonigno Jul 10 '15 at 10:28
0

For me it worked like this:

using (var memoryStream = new MemoryStream())
{
   using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
   {
      var file = archive.CreateEntry("file.json");
      using var entryStream = file.Open();
      using var streamWriter = new StreamWriter(entryStream);
      streamWriter.WriteLine(someJsonLine);
   }
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Dina Bogdan
  • 4,345
  • 5
  • 27
  • 56