Search code examples
c#zipmimemimekit

Invalid Zip File -ZipArchive


I am trying to create a zip file from a byte[] and return the zip file as a byte[] also but when I upload the bytes to blob storage, the zip file is invalid when I download it.

Code:

byte[] zipBytes;
using (var zipMemoryStream = new MemoryStream())
{
    using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Create, true))
    {
        var zipExcelEntry = archive.CreateEntry(
           $"SAR-{subjectAccessRequest.Basic.FirstName}-{subjectAccessRequest.Basic.LastName}_{DateTime.Now:yyyyMMddHHmmss}.xlsx",
           CompressionLevel.Fastest);

        using (var excelEntryFile = zipExcelEntry.Open()) excelEntryFile.Write(stream.ToArray(), 0, (int)stream.Length);

        zipBytes = zipMemoryStream.ToArray();

    };
};

return zipBytes;

Am I doing anything obviously wrong here when creating the zip file?

The code for uploading to blob storage is already tried and tested code so the problem should lie here


Solution

  • You need to close archive before you ToArray the stream.

    You should also use CopyTo on the inner file stream.

    using var zipMemoryStream = new MemoryStream();
    
    using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Create, true))
    {
        var zipExcelEntry = archive.CreateEntry(
               $"SAR-{subjectAccessRequest.Basic.FirstName}-{subjectAccessRequest.Basic.LastName}_{DateTime.Now:yyyyMMddHHmmss}.xlsx",
               CompressionLevel.Fastest);
    
        using (var excelEntryFile = zipExcelEntry.Open())
            stream.CopyTo(excelEntryFile);
    };
    var zipBytes = zipMemoryStream.ToArray();
    return zipBytes;
    

    Ideally you would just return the whole zipped stream rather than creating a new byte array, as this is more efficient.

    var zipMemoryStream = new MemoryStream();
    
    using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Create, true))
    {
        var zipExcelEntry = archive.CreateEntry(
               $"SAR-{subjectAccessRequest.Basic.FirstName}-{subjectAccessRequest.Basic.LastName}_{DateTime.Now:yyyyMMddHHmmss}.xlsx",
               CompressionLevel.Fastest);
    
        using (var excelEntryFile = zipExcelEntry.Open())
            stream.CopyTo(excelEntryFile);
    };
    
    zipMemoryStream.Position = 0;  // reset position to beginning
    return zipMemoryStream;