Cách đọc dữ liệu từ tệp zip mà không cần phải giải nén toàn bộ tệp


97

Có cách nào trong .Net (C #) để trích xuất dữ liệu từ tệp zip mà không cần giải nén tệp hoàn chỉnh không?

Đơn giản là tôi có thể muốn trích xuất dữ liệu (tệp) từ đầu tệp zip, rõ ràng điều này phụ thuộc nếu thuật toán nén nén tệp theo thứ tự xác định.


Câu trả lời:


78

DotNetZip là bạn của bạn ở đây.

Dễ dàng như:

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

(bạn cũng có thể giải nén vào một tệp hoặc các điểm đến khác).

Đọc mục lục của tệp zip dễ dàng như sau:

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

  }
}

Đã chỉnh sửa để lưu ý: DotNetZip từng sống tại Codeplex. Codeplex đã ngừng hoạt động. Các kho lưu trữ cũ vẫn có sẵn tại Codeplex . Có vẻ như mã đã được chuyển sang Github:



9
+1. Đằng sau hậu trường, những gì DotNetZip thực hiện trong hàm tạo là tìm kiếm "thư mục" bên trong tệp zip, sau đó đọc nó và điền vào danh sách các mục nhập. Tại thời điểm đó, nếu ứng dụng của bạn gọi Extract () trên một mục nhập, DotNetZip sẽ tìm đến vị trí thích hợp trong tệp zip và giải nén dữ liệu chỉ cho mục nhập đó.
Cheeso

114

Với .Net Framework 4.5 (sử dụng ZipArchive ):

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

Tìm "myfile" trong zipfile và giải nén nó.


34
Người ta cũng có thể sử dụng entry.Open () để chỉ lấy luồng (nếu nội dung nên được đọc nhưng không được ghi vào tệp).
anre

17
tài liệu tham khảo: System.IO.Compression.dllSystem.IO.Compression.FileSystem.dll
yzorg

18

Một cái gì đó như thế này sẽ liệt kê và giải nén từng tệp một, nếu bạn muốn sử dụng 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());
     }
 }

Dựa trên ví dụ này: nội dung bên trong tệp zip


1
Thành thật mà nói, tôi không thể thấy liên kết này trả lời câu hỏi như thế nào.
Eugene Mayevski 'Gọi lại

10

Đây là cách một tệp văn bản UTF8 có thể được đọc từ một kho lưu trữ zip thành một biến chuỗi (.NET Framework 4.5 trở lên):

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

Tệp zip có mục lục. Mọi tiện ích zip nên có khả năng chỉ truy vấn TOC. Hoặc bạn có thể sử dụng một chương trình dòng lệnh như 7zip -t để in mục lục và chuyển hướng nó đến một tệp văn bản.


0

Trong trường hợp này, bạn sẽ cần phân tích cú pháp các mục nhập tiêu đề cục bộ zip. Mỗi tệp, được lưu trữ trong tệp zip, có mục nhập Tiêu đề tệp cục bộ trước đó, (thông thường) chứa đủ thông tin để giải nén. Nói chung, bạn có thể thực hiện phân tích cú pháp đơn giản các mục như vậy trong luồng, chọn tệp cần thiết, sao chép dữ liệu tiêu đề + tệp nén sang tệp khác và gọi giải nén trên phần đó (nếu bạn không muốn xử lý toàn bộ mã hoặc thư viện giải nén Zip).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.