2017-02-20 1 views
1

Je travaille avec ZipArchive et cela fonctionne principalement, le seul problème que je vois est que lorsque le fichier est téléchargé, je ne peux pas l'ouvrir avec les routines d'archivage par défaut de Windows. Si je clique sur le fichier zip et extrait tout ce que je reçois un message d'erreur qui dit qu'il n'y a pas d'entrées à extraire. quelquun sait pourquoi cela se passe? Pour ce que ça vaut, je peux ouvrir le même fichier avec 7zip et extraire le fichier très bien.ZipArchive crée une entrée ZIP invalide

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"); 
    } 

MISE À JOUR:

Trouvé ce SO Answer et modifié ma source et il fonctionne .... et je ne sais toujours pas pourquoi.

 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(); 
     } 
+1

Que fait 'this.File (...)'? – Dawnkeeper

+0

Je crois que le problème était que je ne disposais pas explicitement de l'entrée. Open() dans le deuxième exemple/mise à jour si ajouté une autre instruction using pour l'entrée et cela semblait me donner le bon comportement. –

Répondre

0

ZipArchive ajouter des informations supplémentaire (eg.checksum) au courant lorsqu'il est disposé, de sorte que vous ne devriez pas chercher le flux ou l'utiliser avant objet ZipArchive est disposé.

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"); 
}