2017-06-04 3 views
-1

J'ai étudié les réponses à des questions similaires, mais je n'en ai vu aucune où plusieurs fichiers sont rassemblés dans un fichier zip pour la transmission au téléchargement. Ce qui suit ne donne aucune erreur mais ne retourne pas un fichier zip reconnaissable.Ziparchive pour plusieurs fichiers dans le flux de la mémoire

public async Task<HttpResponseMessage> SendAZipOfFiles() 
{ 
     var memoryStream = new MemoryStream(); 
     var response = new HttpResponseMessage(HttpStatusCode.OK); 

     List<string> filepaths = await GetSomeFiles(); 
     using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) 
     { 
      foreach (string filepath in filepaths) 
      { 
       string filename = Path.GetFileName(filepath); 
       using (StreamReader reader = new StreamReader(filepath)) 
       using (StreamWriter writer = new StreamWriter(archive.CreateEntry(filename).Open())) 
       { 
        writer.Write(reader.ReadToEnd()); 
       } 
      } 
     } 
     memoryStream.Position = 0; 
     response.Content = new StreamContent(memoryStream); 
     response.Content.Headers.ContentLength = memoryStream.Length; 
     response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
     { 
      FileName = "TheFile.zip") 
     }; 
     response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); 
    return response; 
} 
+0

Side note, mais quand vous cassez la partie passer comme un éclair comme une méthode distincte, il devient beaucoup plus facile à (Test de l'unité. –

Répondre

1

Je vois que vous utilisez StreamReader et StreamWriter, qui sont non seulement inutiles pour votre but, mais peut créer des problèmes d'encodage, car ils sont spécifiquement utilisés pour lire et écrire des fichiers texte.

Si vous avez besoin d'ajouter à vos archives n'importe quel type de fichier et pas seulement les fichiers texte, ils peuvent corrompre les données lors de la lecture/écriture.

Au lieu de cela, il suffit de copier les flux bruts pour archiver les entrées:

public async Task<HttpResponseMessage> SendAZipOfFiles() 
{ 
    var memoryStream = new MemoryStream(); 
    var response = new HttpResponseMessage(HttpStatusCode.OK); 

    List<string> filepaths = await GetSomeFiles(); 
    using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) 
    { 
     foreach (string filepath in filepaths) 
     { 
      string filename = Path.GetFileName(filepath); 
      var entry = archive.CreateEntry(filename); 
      using (var file = File.OpenRead(filename)) 
      using (var entryStream = entry.Open()) 
      { 
        await file.CopyToAsync(entryStream); 
      } 
     } 
    } 
    memoryStream.Position = 0; 
    response.Content = new StreamContent(memoryStream); 
    response.Content.Headers.ContentLength = memoryStream.Length; 
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
    { 
     FileName = "TheFile.zip") 
    }; 
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/zip"); 
    return response; 
} 
0

Il est apparu mon problème était sur le côté dactylographiée.

Je l'ai fait changer le code, en remplacement:

string filename = Path.GetFileName(filepath); 
using (StreamReader reader = new StreamReader(filepath)) 
using (StreamWriter writer = new 
StreamWriter(archive.CreateEntry(filename).Open())) 
{ 
    writer.Write(reader.ReadToEnd()); 
} 

avec le plus simple:

archive.CreateEntryFromFile(filepath, Path.GetFileName(filepath));