web-dev-qa-db-fra.com

Comment créer ZipArchive à partir de fichiers en mémoire en C #?

Est-il possible en quelque sorte de créer un ZipArchive à partir du ou des fichiers en mémoire (et pas réellement sur le disque).

Voici le cas d'utilisation: Plusieurs fichiers sont reçus dans une variable IEnumerable<HttpPostedFileBase>. Je veux compresser tous ces fichiers avec ZipArchive. Le problème est que ZipArchive n'autorise que CreateEntryFromFile, ce qui attend un chemin d'accès au fichier, où je n'ai que les fichiers en mémoire.

Question: Y a-t-il un moyen d'utiliser un "flux" pour créer "l'entrée" dans ZipArchive, afin que je puisse directement mettre le contenu du fichier dans le zip?

Je ne veux pas d'abord enregistrer les fichiers, créer le fichier Zip (à partir des chemins des fichiers enregistrés), puis supprimer les fichiers individuels.

Ici, attachmentFiles est IEnumerable<HttpPostedFileBase>

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var attachment in attachmentFiles)
        {
            zipArchive.CreateEntryFromFile(Path.GetFullPath(attachment.FileName), Path.GetFileName(attachment.FileName),
                                CompressionLevel.Fastest);
        }
    }
    ...
}
13
Flair

Oui, vous pouvez le faire en utilisant la méthode ZipArchive.CreateEntry , comme @AngeloReis l’a souligné dans les commentaires, et décrit ici pour un problème légèrement différent.

Votre code ressemblerait alors à ceci:

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var attachment in attachmentFiles)
        {
            var entry = zipArchive.CreateEntry(attachment.FileName, CompressionLevel.Fastest);
            using (var entryStream = entry.Open())
            {
                attachment.InputStream.CopyTo(entryStream);
            }
        }
    }
    ...
}
18
Alex

Tout d’abord, merci @Alex pour la réponse parfaite.
Pour le scénario que vous devez lire à partir de systèmes de fichiers: 

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var file in filesAddress)
        {
            zipArchive.CreateEntryFromFile(file, Path.GetFileName(file));
        }
    }

    ...
}

avec l'aide de System.IO.Compression.ZipFileExtensions

0
Soren