Cara membaca data dari file zip tanpa harus mengekstrak seluruh file

97

Apakah tetap ada di .Net (C #) untuk mengekstrak data dari file zip tanpa mendekompresi file lengkap?

Sederhananya saya mungkin ingin mengekstrak data (file) dari awal file zip, jelas ini tergantung jika algoritma kompresi memampatkan file dalam urutan deterministik.

AwkwardCoder
sumber

Jawaban:

78

DotNetZip adalah teman Anda di sini.

Semudah:

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

(Anda juga dapat mengekstrak ke file atau tujuan lain).

Membaca daftar isi file zip semudah:

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

  }
}

Diedit Untuk Catatan: DotNetZip dulu tinggal di Codeplex. Codeplex telah dimatikan. Arsip lama masih tersedia di Codeplex . Sepertinya kode telah bermigrasi ke Github:


Nicholas Carey
sumber
9
+1. Di balik layar, apa yang dilakukan DotNetZip di konstruktor adalah mencari "direktori" di dalam zipfile, lalu membacanya dan mengisi daftar entri. Pada titik itu, jika aplikasi Anda memanggil Extract () pada satu entri, DotNetZip mencari tempat yang tepat di file zip, dan mendekompresi data hanya untuk entri itu.
Cheeso
115

Dengan .Net Framework 4.5 (menggunakan ZipArchive ):

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

Temukan "myfile" di zipfile dan ekstrak.

Sinatr
sumber
35
Seseorang juga dapat menggunakan entry.Open () untuk hanya mendapatkan aliran (jika isinya harus dibaca tetapi tidak ditulis ke file).
anre
17
referensi: System.IO.Compression.dlldanSystem.IO.Compression.FileSystem.dll
yzorg
18

Sesuatu seperti ini akan mendaftar dan mengekstrak file satu per satu, jika Anda ingin menggunakan 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());
     }
 }

Berdasarkan contoh ini: konten di dalam file zip

Javi
sumber
1
Terus terang, saya tidak bisa melihat bagaimana link ini menjawab pertanyaan tersebut.
Panggilan balik Eugene Mayevski
10

Berikut adalah bagaimana file teks UTF8 dapat dibaca dari arsip zip menjadi variabel string (.NET Framework 4.5 dan lebih tinggi):

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
sumber
0

File zip memiliki daftar isi. Setiap utilitas zip harus memiliki kemampuan untuk menanyakan TOC saja. Atau Anda dapat menggunakan program baris perintah seperti 7zip -t untuk mencetak daftar isi dan mengarahkannya ke file teks.

umilmi81
sumber
0

Jika demikian, Anda perlu mengurai entri header lokal zip. Setiap file, disimpan dalam file zip, memiliki entri Header File Lokal sebelumnya, yang (biasanya) berisi informasi yang cukup untuk dekompresi, Umumnya, Anda dapat membuat parsing sederhana dari entri tersebut dalam aliran, memilih file yang diperlukan, menyalin header + data file terkompresi ke file lain. file, dan panggil unzip pada bagian itu (jika Anda tidak ingin berurusan dengan seluruh kode atau pustaka dekompresi Zip).

Nickolay Olshevsky
sumber