web-dev-qa-db-fra.com

Comment décompresser un fichier dans un flux de mémoire .NET?

J'ai des fichiers (provenant de tiers) qui sont en cours de transfert FTP vers un répertoire de notre serveur. Je les télécharge et les traite même "x" minutes. Fonctionne très bien.

Maintenant, certains fichiers sont .Zip des dossiers. Ce qui signifie que je ne peux pas les traiter. Je dois d'abord les décompresser.

FTP n'a pas de concept de Zip/décompression - donc je vais devoir récupérer le fichier Zip, le décompresser, puis le traiter.

En regardant MSDN Zip api , il semble qu'il n'y ait aucun moyen de décompresser un flux de mémoire?

C'est donc la seule façon de le faire ...

  1. Décompressez dans un fichier (quel répertoire? Besoin d'un emplacement -very-temp ...)
  2. Lire le contenu du fichier
  3. Supprimer le fichier.

REMARQUE: le contenu du fichier est petit - disons 4k <-> 1000k.

29
Pure.Krome

La prise en charge de la compression Zip est intégrée:

using System.IO;
using System.IO.Compression;
// ^^^ requires a reference to System.IO.Compression.dll
static class Program
{
    const string path = ...
    static void Main()
    {
        using(var file = File.OpenRead(path))
        using(var Zip = new ZipArchive(file, ZipArchiveMode.Read))
        {
            foreach(var entry in Zip.Entries)
            {
                using(var stream = entry.Open())
                {
                    // do whatever we want with stream
                    // ...
                }
            }
        }
    }
}

Normalement, vous devriez éviter de le copier dans un autre flux - utilisez-le simplement "tel quel", cependant, si vous en avez absolument besoin dans un MemoryStream, vous pouvez faire:

using(var ms = new MemoryStream())
{
    stream.CopyTo(ms);
    ms.Position = 0; // rewind
    // do something with ms
}
61
Marc Gravell

Vous pouvez utiliser ZipArchiveEntry.Open pour obtenir un flux.

Ce code suppose que l'archive Zip possède un fichier texte.

using (FileStream fs = new FileStream(path, FileMode.Open))
using (ZipArchive Zip = new ZipArchive(fs) )
{
    var entry = Zip.Entries.First();

    using (StreamReader sr = new StreamReader(entry.Open()))
    {
        Console.WriteLine(sr.ReadToEnd());
    }
}
9
dcastro

On dirait que voici ce dont vous avez besoin:

   using (var za = ZipFile.OpenRead(path))
   {
       foreach (var entry in sa.Entries)
       {
                using (var r = new StreamReader(entry.Open()))
                {
                    //your code here
                }
       }
   }
5
Uriil
  using (ZipArchive archive = new ZipArchive(webResponse.GetResponseStream()))
      {
      foreach (ZipArchiveEntry entry in archive.Entries)
          {
          Stream s = entry.Open();
          var sr = new StreamReader(s);
          var myStr = sr.ReadToEnd();
          }
      } 
4
Zia Khan