So lesen Sie Daten aus einer Zip-Datei, ohne die gesamte Datei entpacken zu müssen

97

Gibt es in .Net (C #) überhaupt die Möglichkeit, Daten aus einer Zip-Datei zu extrahieren, ohne die gesamte Datei zu dekomprimieren?

Ich möchte möglicherweise einfach Daten (Dateien) vom Anfang einer Zip-Datei extrahieren. Dies hängt natürlich davon ab, ob der Komprimierungsalgorithmus die Datei in einer deterministischen Reihenfolge komprimiert.

AwkwardCoder
quelle

Antworten:

78

DotNetZip ist dein Freund hier.

So leicht wie:

using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
  ZipEntry e = zip["MyReport.doc"];
  e.Extract(OutputStream);
}

(Sie können auch in eine Datei oder andere Ziele extrahieren).

Das Lesen des Inhaltsverzeichnisses der Zip-Datei ist so einfach wie:

using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
  foreach (ZipEntry e in zip)
  {
    if (header)
    {
      System.Console.WriteLine("Zipfile: {0}", zip.Name);
      if ((zip.Comment != null) && (zip.Comment != "")) 
        System.Console.WriteLine("Comment: {0}", zip.Comment);
      System.Console.WriteLine("\n{1,-22} {2,8}  {3,5}   {4,8}  {5,3} {0}",
                               "Filename", "Modified", "Size", "Ratio", "Packed", "pw?");
      System.Console.WriteLine(new System.String('-', 72));
      header = false;
    }
    System.Console.WriteLine("{1,-22} {2,8} {3,5:F0}%   {4,8}  {5,3} {0}",
                             e.FileName,
                             e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"),
                             e.UncompressedSize,
                             e.CompressionRatio,
                             e.CompressedSize,
                             (e.UsesEncryption) ? "Y" : "N");

  }
}

Bearbeitet, um zu beachten: DotNetZip lebte früher bei Codeplex. Codeplex wurde heruntergefahren. Das alte Archiv ist weiterhin bei Codeplex verfügbar . Es sieht so aus, als ob der Code nach Github migriert wurde:


Nicholas Carey
quelle
9
+1. Hinter den Kulissen sucht DotNetZip im Konstruktor nach dem "Verzeichnis" in der Zip-Datei, liest es und füllt die Liste der Einträge. Wenn Ihre App zu diesem Zeitpunkt Extract () für einen Eintrag aufruft, sucht DotNetZip an der richtigen Stelle in der Zip-Datei und dekomprimiert die Daten nur für diesen Eintrag.
Cheeso
112

Mit .Net Framework 4.5 (mit ZipArchive ):

using (ZipArchive zip = ZipFile.Open(zipfile, ZipArchiveMode.Read))
    foreach (ZipArchiveEntry entry in zip.Entries)
        if(entry.Name == "myfile")
            entry.ExtractToFile("myfile");

Finde "myfile" in zipfile und extrahiere es.

Sinatr
quelle
33
Man kann auch entry.Open () verwenden, um nur den Stream abzurufen (wenn der Inhalt gelesen, aber nicht in eine Datei geschrieben werden soll).
Anre
17
Referenzen: System.IO.Compression.dllundSystem.IO.Compression.FileSystem.dll
Yzorg
18

In etwa so werden die Dateien einzeln aufgelistet und extrahiert, wenn Sie SharpZipLib verwenden möchten:

var zip = new ZipInputStream(File.OpenRead(@"C:\Users\Javi\Desktop\myzip.zip"));
var filestream = new FileStream(@"C:\Users\Javi\Desktop\myzip.zip", FileMode.Open, FileAccess.Read);
ZipFile zipfile = new ZipFile(filestream);
ZipEntry item;
while ((item = zip.GetNextEntry()) != null)
{
     Console.WriteLine(item.Name);
     using (StreamReader s = new StreamReader(zipfile.GetInputStream(item)))
     {
      // stream with the file
          Console.WriteLine(s.ReadToEnd());
     }
 }

Basierend auf diesem Beispiel: Inhalt in der Zip-Datei

Javi
quelle
1
Ehrlich gesagt konnte ich nicht sehen, wie dieser Link die Frage beantwortet.
Eugene Mayevski 'Rückruf
10

So kann eine UTF8-Textdatei aus einem Zip-Archiv in eine Zeichenfolgenvariable (.NET Framework 4.5 und höher) gelesen werden:

string zipFileFullPath = "{{TypeYourZipFileFullPathHere}}";
string targetFileName = "{{TypeYourTargetFileNameHere}}";
string text = new string(
            (new System.IO.StreamReader(
             System.IO.Compression.ZipFile.OpenRead(zipFileFullPath)
             .Entries.Where(x => x.Name.Equals(targetFileName,
                                          StringComparison.InvariantCulture))
             .FirstOrDefault()
             .Open(), Encoding.UTF8)
             .ReadToEnd())
             .ToArray());
ShamilS
quelle
0

Zip-Dateien haben ein Inhaltsverzeichnis. Jedes Zip-Dienstprogramm sollte nur das Inhaltsverzeichnis abfragen können. Oder Sie können ein Befehlszeilenprogramm wie 7zip -t verwenden, um das Inhaltsverzeichnis zu drucken und in eine Textdatei umzuleiten.

umilmi81
quelle
0

In diesem Fall müssen Sie lokale Zip-Header-Einträge analysieren. Jede in einer Zip-Datei gespeicherte Datei verfügt über einen vorangegangenen Eintrag für den lokalen Dateikopf, der (normalerweise) genügend Informationen für die Dekomprimierung enthält. Im Allgemeinen können Sie solche Einträge im Stream einfach analysieren, die erforderliche Datei auswählen, den Kopf und die komprimierten Dateidaten in andere kopieren Datei und rufen Sie Unzip für diesen Teil auf (wenn Sie nicht mit dem gesamten Zip-Dekomprimierungscode oder der Bibliothek arbeiten möchten).

Nickolay Olshevsky
quelle