Como ler dados de um arquivo zip sem ter que descompactar todo o arquivo


Respostas:


78

DotNetZip é seu amigo aqui.

Tão fácil quanto:

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

(você também pode extrair para um arquivo ou outros destinos).

Ler o índice do arquivo zip é tão fácil quanto:

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

  }
}

Editado para Nota: DotNetZip costumava morar no Codeplex. Codeplex foi encerrado. O arquivo antigo ainda está disponível no Codeplex . Parece que o código migrou para o Github:



9
+1. Nos bastidores, o que DotNetZip faz no construtor é buscar o "diretório" dentro do arquivo zip, e então lê-lo e preencher a lista de entradas. Nesse ponto, se seu aplicativo chamar Extract () em uma entrada, o DotNetZip buscará o local adequado no arquivo zip e descompactará os dados apenas para essa entrada.
Cheeso de

114

Com .Net Framework 4.5 (usando ZipArchive ):

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

Encontre "myfile" em zipfile e extraia-o.


34
Também é possível usar entry.Open () apenas para obter o fluxo (se o conteúdo deve ser lido, mas não escrito em um arquivo).
anre

17
referências: System.IO.Compression.dlleSystem.IO.Compression.FileSystem.dll
yzorg

18

Algo assim irá listar e extrair os arquivos um por um, se você quiser usar o 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());
     }
 }

Com base neste exemplo: conteúdo dentro do arquivo zip


1
Falando francamente, não consegui ver como esse link responde à pergunta.
Callback de Eugene Mayevski

10

Veja como um arquivo de texto UTF8 pode ser lido de um arquivo zip em uma variável de string (.NET Framework 4.5 e superior):

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

Os arquivos Zip possuem um índice. Cada utilitário zip deve ter a capacidade de consultar apenas o TOC. Ou você pode usar um programa de linha de comando como 7zip -t para imprimir o índice e redirecioná-lo para um arquivo de texto.


0

Nesse caso, você precisará analisar as entradas do cabeçalho local zip. Cada arquivo, armazenado em um arquivo zip, tem uma entrada de Cabeçalho de Arquivo Local anterior, que (normalmente) contém informações suficientes para descompactação. Geralmente, você pode fazer uma análise simples de tais entradas no fluxo, selecionar o arquivo necessário, copiar o cabeçalho + dados do arquivo compactado para outro arquivo e chame unzip nessa parte (se você não quiser lidar com todo o código de descompressão Zip ou biblioteca).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.