Jak odczytać dane z pliku zip bez konieczności rozpakowywania całego pliku

97

Czy w programie .Net (C #) istnieje możliwość wyodrębnienia danych z pliku zip bez dekompresowania całego pliku?

Po prostu chcę wyodrębnić dane (plik) z początku pliku zip, oczywiście zależy to od tego, czy algorytm kompresji kompresuje plik w kolejności deterministycznej.

AwkwardCoder
źródło

Odpowiedzi:

78

DotNetZip jest tutaj twoim przyjacielem.

Łatwy jak:

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

(możesz także rozpakować do pliku lub innych miejsc docelowych).

Czytanie spisu treści pliku zip jest tak proste, jak:

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

  }
}

Zmieniono do uwagi: DotNetZip mieszkał w Codeplex. Codeplex został zamknięty. Stare archiwum jest nadal dostępne w Codeplex . Wygląda na to, że kod został przeniesiony do Github:


Nicholas Carey
źródło
9
+1. W tle, to, co robi DotNetZip w konstruktorze, to przeszukiwanie „katalogu” w pliku zip, a następnie przeczytanie go i wypełnienie listy wpisów. W tym momencie, jeśli Twoja aplikacja wywoła Extract () na jednym wpisie, DotNetZip szuka odpowiedniego miejsca w pliku zip i dekompresuje dane tylko dla tego wpisu.
Cheeso
115

Z .Net Framework 4.5 (przy użyciu ZipArchive ):

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

Znajdź „myfile” w zipfile i rozpakuj go.

Sinatr
źródło
35
Można również użyć metody entry.Open (), aby po prostu pobrać strumień (jeśli zawartość ma być czytana, ale nie zapisywana do pliku).
anre
17
referencje: System.IO.Compression.dlliSystem.IO.Compression.FileSystem.dll
yzorg
18

Coś takiego wyświetli listę i wyodrębni pliki jeden po drugim, jeśli chcesz użyć SharpZipLib:

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

Na podstawie tego przykładu: zawartość w pliku zip

Javi
źródło
1
Szczerze mówiąc, nie mogłem zobaczyć, jak ten link odpowiada na pytanie.
Eugene Mayevski 'Callback
10

Oto jak plik tekstowy UTF8 może być odczytany z archiwum zip do zmiennej typu string (.NET Framework 4.5 i nowsze):

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
źródło
0

Pliki ZIP zawierają spis treści. Każde narzędzie zip powinno mieć możliwość wysyłania zapytań tylko do spisu treści. Lub możesz użyć programu wiersza poleceń, takiego jak 7zip -t, aby wydrukować spis treści i przekierować go do pliku tekstowego.

umilmi81
źródło
0

W takim przypadku będziesz musiał przeanalizować lokalne wpisy nagłówka zip. Każdy plik, przechowywany w pliku zip, ma poprzedzający wpis nagłówka pliku lokalnego, który (normalnie) zawiera wystarczającą ilość informacji do dekompresji, generalnie można wykonać prostą analizę takich wpisów w strumieniu, wybrać potrzebny plik, skopiować nagłówek + skompresowane dane pliku do innego file i wywołaj unzip w tej części (jeśli nie chcesz zajmować się całym kodem lub biblioteką dekompresyjną Zip).

Nickolay Olshevsky
źródło