2011-05-11 36 views
68

¿Hay alguna forma en .Net (C#) para extraer datos de un archivo comprimido sin descomprimir el archivo completo?Cómo leer datos de un archivo comprimido sin tener que descomprimir el archivo completo

Simplemente, posiblemente quiero extraer los 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.

+3

Esta cuestión está redactada de una manera que es difícil de entender, Recomendaría actualizar el título de su pregunta para que se parezca más a las líneas "Cómo leer datos de un archivo comprimido sin tener que descomprimir el archivo completo" –

+0

@Chris Cambié el título de acuerdo con su sugerencia, acepto que es más fácil de entender rápidamente . – JYelton

+0

Dupe de http://stackoverflow.com/questions/328343/using-sharpziplib-to-unzip-specific-files? – Magnus

Respuesta

63

DotNetZip es tu amigo aquí.

Tan fácil como:

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

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

lectura mesa del archivo zip de contenidos 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"); 

    } 
} 
+8

+1. Detrás de escena, lo que hace DotNetZip en el constructor es buscar en 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 adecuado en el archivo comprimido y descomprime los datos para esa entrada. – Cheeso

14

Algo como esto hará una lista y extraer los archivos de uno en 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()); 
    } 
} 

En base a este ejemplo: content inside zip file

+1

Francamente hablando, no pude ver cómo este enlace responde la pregunta. –

0

archivos Zip tienen un índice de contenidos. Cada utilidad de compresión debe tener la capacidad de consultar solo el TOC. O puede usar un programa de línea de comando como 7zip -t para imprimir la tabla de contenido y redirigirla a un archivo de texto.

0

En tal caso, tendrá que analizar zip entradas de cabecera locales. Cada archivo, almacenado en archivo zip, tiene una entrada de encabezado de archivo local anterior, que (normalmente) contiene suficiente información para la descompresión. Generalmente, puede realizar un análisis simple de tales entradas en la secuencia, seleccionar el archivo necesario, copiar el encabezado + datos de archivo comprimido a otra archivo, y llamada descomprimir en esa parte (si no desea tratar con todo el código de descompresión Zip o la biblioteca).

78

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

Find "miarchivo" en el archivo zip y extraerlo.

+20

También se puede usar entry.Open() para obtener solo la secuencia (si el contenido debe leerse pero no escribirse en un archivo). – anre

+7

referencias: 'System.IO.Compression.dll' y' System.IO.Compression.FileSystem.dll' – yzorg

1

Así es como un archivo de texto UTF-8 se puede leer en un archivo zip en una variable de cadena (.NET Framework 4.5 en adelante):

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()); 
Cuestiones relacionadas