Как читать данные из zip-файла без необходимости распаковывать весь файл

98

Есть ли способ в .Net (C #) извлекать данные из zip-файла без распаковки всего файла?

Просто я, возможно, хочу извлечь данные (файл) с начала zip-файла, очевидно, это зависит от того, сжимает ли алгоритм сжатия файл в детерминированном порядке.

AwkwardCoder
источник
Обманывать stackoverflow.com/questions/328343/… ?
Магнус

Ответы:

78

DotNetZip - ваш друг.

Так же легко, как:

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

(вы также можете извлечь в файл или в другое место назначения).

Прочитать оглавление zip-файла так же просто:

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

  }
}

Отредактировано для примечания: DotNetZip раньше жил в Codeplex. Codeplex был закрыт. Старый архив все еще доступен на Codeplex . Похоже, код перекочевал на Github:


Николас Кэри
источник
9
+1. За кулисами DotNetZip в конструкторе ищет «каталог» внутри zip-файла, а затем читает его и заполняет список записей. В этот момент, если ваше приложение вызывает Extract () для одной записи, DotNetZip ищет нужное место в zip-файле и распаковывает данные только для этой записи.
Cheeso
116

С .Net Framework 4.5 (с использованием ZipArchive ):

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

Найдите «myfile» в zip-архиве и распакуйте его.

Sinatr
источник
36
Также можно использовать entry.Open (), чтобы просто получить поток (если содержимое должно быть прочитано, но не записано в файл).
anre
17
ссылки: System.IO.Compression.dllandSystem.IO.Compression.FileSystem.dll
yzorg
18

Что-то вроде этого будет перечислять и извлекать файлы один за другим, если вы хотите использовать 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());
     }
 }

На основе этого примера: содержимое внутри zip-файла

Хави
источник
1
Честно говоря, я не мог понять, как эта ссылка отвечает на вопрос.
Обратный звонок Евгения Маевского
10

Вот как текстовый файл UTF8 можно прочитать из zip-архива в строковую переменную (.NET Framework 4.5 и выше):

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());
ШамильС
источник
0

Zip-файлы имеют оглавление. Каждая утилита zip должна иметь возможность запрашивать только оглавление. Или вы можете использовать программу командной строки, например 7zip -t, чтобы распечатать оглавление и перенаправить его в текстовый файл.

umilmi81
источник
0

В таком случае вам нужно будет проанализировать записи локального заголовка zip-архива. Каждый файл, хранящийся в zip-файле, имеет предшествующую запись локального заголовка файла, которая (обычно) содержит достаточно информации для распаковки. Как правило, вы можете выполнить простой анализ таких записей в потоке, выбрать необходимый файл, скопировать заголовок + данные сжатого файла в другой файл и вызовите unzip в этой части (если вы не хотите иметь дело со всем кодом или библиотекой распаковки Zip).

Николай Ольшевский
источник