Cómo leer datos de un archivo zip sin tener que descomprimir el archivo completo

97

¿Hay alguna forma en .Net (C #) para extraer datos de un archivo zip sin descomprimir el archivo completo?

Simplemente, posiblemente quiera extraer datos (archivo) desde el inicio de un archivo zip, obviamente, esto depende de si el algoritmo de compresión comprime el archivo en un orden determinista.

AwkwardCoder
fuente

Respuestas:

78

DotNetZip es tu amigo aquí.

Tan fácil como:

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

(también puede extraer a un archivo u otros destinos).

Leer la tabla de contenido del archivo zip es tan fácil como:

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 solía vivir en Codeplex. Codeplex se ha cerrado. El archivo antiguo todavía está disponible en Codeplex . Parece que el código se ha migrado a Github:


Nicolás Carey
fuente
9
+1. Detrás de escena, lo que hace DotNetZip en el constructor es buscar el "directorio" dentro del archivo zip, y luego leerlo y completar la lista de entradas. En ese momento, si su aplicación llama a Extract () en una entrada, DotNetZip busca el lugar correcto en el archivo zip y descomprime los datos solo para esa entrada.
Cheeso
115

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

Busque "myfile" en zipfile y extráigalo.

Sinatr
fuente
35
También se puede usar entry.Open () para obtener el flujo (si el contenido debe leerse pero no escribirse en un archivo).
anre el
17
referencias: System.IO.Compression.dllySystem.IO.Compression.FileSystem.dll
yzorg
18

Algo como esto enumerará y extraerá los archivos uno por uno, si desea utilizar 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());
     }
 }

Basado en este ejemplo: contenido dentro del archivo zip

Javi
fuente
1
Hablando francamente, no pude ver cómo este enlace responde a la pregunta.
Devolución de llamada de Eugene Mayevski
10

Así es como se puede leer un archivo de texto UTF8 desde un archivo zip en una variable de cadena (.NET Framework 4.5 y 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());
ShamilS
fuente
0

Los archivos zip tienen una tabla de contenido. Cada utilidad zip debe tener la capacidad de consultar solo la tabla de contenido. O puede utilizar un programa de línea de comandos como 7zip -t para imprimir la tabla de contenido y redirigirla a un archivo de texto.

umilmi81
fuente
0

En tal caso, deberá analizar las entradas del encabezado local zip. Cada archivo, almacenado en un archivo zip, tiene una entrada de encabezado de archivo local anterior, que (normalmente) contiene suficiente información para la descompresión.En general, puede realizar un análisis simple de dichas entradas en la secuencia, seleccionar el archivo necesario, copiar el encabezado + los datos del archivo comprimido a otro file, y llame a descomprimir en esa parte (si no desea tratar con todo el código de descompresión Zip o la biblioteca).

Nickolay Olshevsky
fuente