2008-11-21 8 views
22

Làm thế nào để liệt kê các nội dung của một thư mục nén trong C#? Ví dụ như làm thế nào để biết có bao nhiêu mục được chứa trong một thư mục nén, và tên của họ là gì?Cách liệt kê nội dung của thư mục .zip trong C#?

+0

Trong trường hợp .NET 4.5 trở lên, bạn không cần thư viện của bên thứ ba nữa! Xem câu trả lời của tôi dưới đây! Liên kết –

Trả lời

12

Kiểm tra thành SharpZipLib

ZipInputStream inStream = new ZipInputStream(File.OpenRead(fileName)) 

While (isnStream.GetNextEntry) 
{ 

    entry = inStream.GetNextEntry(); 
    //write out your entry's filename 
} 
+1

: http://www.icsharpcode.net/OpenSource/SharpZipLib/ – dnolan

3

Có một số thư viện cho NET có sẵn, với yêu cầu cấp phép khác nhau.

Dưới đây là một bài viết giới thiệu về chủ đề này: Article

29

DotNetZip - Zip thao tác tập tin bằng các ngôn ngữ .NET

DotNetZip là một, dễ sử dụng thư viện lớp học nhỏ cho các thao tác .zip file. Nó có thể kích hoạt các ứng dụng .NET được viết bằng VB.NET, C#, bất kỳ ngôn ngữ .NET nào, để dễ dàng tạo, đọc và cập nhật các tệp zip.

mẫu mã để đọc một zip:

using (var zip = ZipFile.Read(PathToZipFolder)) 
{ 
    int totalEntries = zip.Entries.Count; 
    foreach (ZipEntry e in zip.Entries) 
    { 
     e.FileName ... 
     e.CompressedSize ... 
     e.LastModified... 
    } 
} 
+10

Tại sao điều này lại bị bỏ phiếu? Nó trả lời câu hỏi. – Kev

21

Nếu bạn đang sử dụng Net Framework 3.0 hoặc mới hơn, kiểm tra System.IO.Packaging Namespace. Điều này sẽ loại bỏ sự phụ thuộc của bạn trên một thư viện bên ngoài.

Kiểm tra cụ thể ZipPackage Class.

+1

Nó loại bỏ sự phụ thuộc vào một thư viện bên ngoài, nhưng khả năng sử dụng của ZipPackage thực sự không phải là rất tốt. Tất cả mọi thứ là một thương mại tắt! – Cheeso

+0

'ZipPackage' được thiết kế để xử lý chủ yếu các định dạng tệp liên quan đến Microsoft mà tệp nội bộ là các tệp zip, chẳng hạn như:' docx', 'xlsx',' XPS', 'nupkg' .... Từ quan điểm chung của tệp zip, chúng chỉ khác nhau vì sự hiện diện của tệp 'Content_Type.xml' được đặt trong thư mục gốc của tệp lưu trữ. Nếu bạn không thể sử dụng .NET 4.5, nhưng có thể sử dụng .NET 3.0, 'ZipPackage' có thể hoàn hảo do bạn tạo và tiêu thụ tệp. –

+1

Đối với .NET 4.5 hoặc cao hơn, nên sử dụng lớp 'ZipArchive' cho mục đích nén chung, xem câu trả lời của tôi bên dưới –

4

Tôi khá mới ở đây nên có thể tôi không hiểu chuyện gì đang diễn ra. :-) Hiện tại có 4 câu trả lời về chủ đề này, nơi hai câu trả lời hay nhất đã được bỏ phiếu. (Pearcewg's và cxfx's) Bài báo được chỉ ra bởi pearcewg là quan trọng vì nó làm rõ một số vấn đề cấp phép với SharpZipLib. Gần đây chúng tôi đã đánh giá một số thư viện nén .Net và nhận thấy rằng DotNetZip hiện là phương pháp tốt nhất.

tóm tắt rất ngắn:

  • System.IO.Packaging là chậm hơn so với DotNetZip đáng kể.

  • SharpZipLib là GPL - xem bài viết.

Vì vậy, để bắt đầu, tôi đã bỏ phiếu cho hai câu trả lời đó.

Kim.

+1

Bản thân GPL giải quyết vấn đề một phần của chương trình không phải là" phái sinh "của mã GPL và quyền của chúng được cấp phép độc lập. Tôi không thấy SharpZipLib là GPL là một vấn đề quan trọng. – GalacticCowboy

+1

GC, bạn đang nói rằng nếu một nhóm hoặc tổ chức có vấn đề với GPL thì nhóm đó sai? Hay là bạn không thể hiểu được bất cứ ai có vấn đề với GPL, bao giờ? Nó không quá khó tin. Báo chí tràn đầy những câu chuyện về các bài kiểm tra pháp lý đắt tiền. – Cheeso

+2

Vâng, GPL là virus. Nếu anh ta làm phần mềm nguồn đóng thương mại, và anh ta liên kết mã của mình với một thư viện GPL, thì anh ta phải giải phóng nguồn của mình theo giấy phép tương thích GPL. Vì vậy, có, thực tế là SharpZibLib là GPL là một vấn đề quan trọng. – cdmckay

0

Cách tốt nhất là sử dụng .NET được xây dựng trong chức năng zip # J, như được hiển thị trong MSDN: http://msdn.microsoft.com/en-us/magazine/cc164129.aspx. Trong liên kết này có một ví dụ làm việc hoàn chỉnh về một ứng dụng đọc và ghi vào các tệp zip. Đối với ví dụ cụ thể về danh sách các nội dung của một file zip (trong trường hợp này là một gói ứng dụng .xap Silverlight), các mã có thể trông như thế này:


ZipFile package = new ZipFile(packagePath); 
java.util.Enumeration entries = package.entries(); 
//We have to use Java enumerators because we 
//use java.util.zip for reading the .zip files 
while (entries.hasMoreElements()) 
{ 
    ZipEntry entry = (ZipEntry) entries.nextElement(); 

    if (!entry.isDirectory()) 
    { 
     string name = entry.getName(); 
     Console.WriteLine("File: " + name + ", size: " + entry.getSize() + ", compressed size: " + entry.getCompressedSize()); 
    } 
    else 
    { 
     // Handle directories... 
    }       
} 

Aydsman có một con trỏ phải, nhưng có problems. Cụ thể, bạn có thể tìm thấy sự cố khi mở tệp zip, nhưng là giải pháp hợp lệ nếu bạn định chỉ chỉ tạo pacakges. ZipPackage triển khai lớp Package trừu tượng và cho phép thao tác các file zip. Có một mẫu làm thế nào để làm điều đó trong MSDN: http://msdn.microsoft.com/en-us/library/ms771414.aspx.Khoảng mã sẽ trông như thế này:

   string packageRelationshipType = @"http://schemas.microsoft.com/opc/2006/sample/document"; 
      string resourceRelationshipType = @"http://schemas.microsoft.com/opc/2006/sample/required-resource"; 
      // Open the Package. 
      // ('using' statement insures that 'package' is 
      // closed and disposed when it goes out of scope.) 
      foreach (string packagePath in downloadedFiles) 
      { 
       Logger.Warning("Analyzing " + packagePath); 
       using (Package package = Package.Open(packagePath, FileMode.Open, FileAccess.Read)) 
       { 
        Logger.OutPut("package opened"); 
        PackagePart documentPart = null; 
        PackagePart resourcePart = null; 

        // Get the Package Relationships and look for 
        // the Document part based on the RelationshipType 
        Uri uriDocumentTarget = null; 
        foreach (PackageRelationship relationship in 
         package.GetRelationshipsByType(packageRelationshipType)) 
        { 
         // Resolve the Relationship Target Uri 
         // so the Document Part can be retrieved. 
         uriDocumentTarget = PackUriHelper.ResolvePartUri(
          new Uri("/", UriKind.Relative), relationship.TargetUri); 

         // Open the Document Part, write the contents to a file. 
         documentPart = package.GetPart(uriDocumentTarget); 
         //ExtractPart(documentPart, targetDirectory); 
         string stringPart = documentPart.Uri.ToString().TrimStart('/'); 
         Logger.OutPut(" Got: " + stringPart); 
        } 

        // Get the Document part's Relationships, 
        // and look for required resources. 
        Uri uriResourceTarget = null; 
        foreach (PackageRelationship relationship in 
         documentPart.GetRelationshipsByType(
               resourceRelationshipType)) 
        { 
         // Resolve the Relationship Target Uri 
         // so the Resource Part can be retrieved. 
         uriResourceTarget = PackUriHelper.ResolvePartUri(
          documentPart.Uri, relationship.TargetUri); 

         // Open the Resource Part and write the contents to a file. 
         resourcePart = package.GetPart(uriResourceTarget); 

         //ExtractPart(resourcePart, targetDirectory); 
         string stringPart = resourcePart.Uri.ToString().TrimStart('/'); 
         Logger.OutPut(" Got: " + stringPart); 
        } 

       } 
      } 

Cách tốt nhất dường như sử dụng J #, như thể hiện trong MSDN: http://msdn.microsoft.com/en-us/magazine/cc164129.aspx

Có con trỏ đến hơn c thư viện # .zip với giấy phép khác nhau, như SharpNetZip và DotNetZip trong bài viết này: how to read files from uncompressed zip in c#?. Chúng có thể không phù hợp vì yêu cầu giấy phép.

+5

không, đây không phải là tốt nhất.Thời gian chạy J # được dựa trên một thư viện Java cũ, các công cụ zip có lỗi và nó sẽ không hỗ trợ. – Cheeso

6

Ick - mã đó sử dụng thời gian chạy J # rất ghê gớm! Và tôi không đồng ý rằng đó là cách tốt nhất - J # hiện không còn hỗ trợ nữa. Và nó là một thời gian chạy HUGE, nếu tất cả những gì bạn muốn là hỗ trợ ZIP.

Làm thế nào về điều này - nó sử dụng DotNetZip (miễn phí giấy phép MS-Công)

using (ZipFile zip = ZipFile.Read(zipfile)) 
{ 
    bool header = true; 
    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,9} {3,5} {4,9} {5,3} {6,8} {0}", 
            "Filename", "Modified", "Size", "Ratio", "Packed", "pw?", "CRC"); 
      System.Console.WriteLine(new System.String('-', 80)); 
      header = false; 
     } 

     System.Console.WriteLine("{1,-22} {2,9} {3,5:F0}% {4,9} {5,3} {6:X8} {0}", 
           e.FileName, 
           e.LastModified.ToString("yyyy-MM-dd HH:mm:ss"), 
           e.UncompressedSize, 
           e.CompressionRatio, 
           e.CompressedSize, 
           (e.UsesEncryption) ? "Y" : "N", 
           e.Crc32); 

     if ((e.Comment != null) && (e.Comment != "")) 
      System.Console.WriteLine(" Comment: {0}", e.Comment); 
    } 
} 
4

Nếu bạn đang như tôi và không muốn sử dụng một thành phần bên ngoài, đây là một số mã tôi phát triển đêm qua sử dụng Lớp ZipPackage của .NET.

var zipFilePath = "c:\\myfile.zip"; 
var tempFolderPath = "c:\\unzipped"; 

using (Package package = ZipPackage.Open(zipFilePath, FileMode.Open, FileAccess.Read)) 
{ 
    foreach (PackagePart part in package.GetParts()) 
    { 
     var target = Path.GetFullPath(Path.Combine(tempFolderPath, part.Uri.OriginalString.TrimStart('/'))); 
     var targetDir = target.Remove(target.LastIndexOf('\\')); 

     if (!Directory.Exists(targetDir)) 
      Directory.CreateDirectory(targetDir); 

     using (Stream source = part.GetStream(FileMode.Open, FileAccess.Read)) 
     { 
      source.CopyTo(File.OpenWrite(target)); 
     } 
    } 
} 

Những điều cần lưu ý:

  • Các kho lưu trữ ZIP PHẢI có một [Content_Types] .xml tập tin trong thư mục gốc của nó. Đây không phải là vấn đề đối với các yêu cầu của tôi vì tôi sẽ kiểm soát việc nén của bất kỳ tệp ZIP nào được trích xuất thông qua mã này. Để biết thêm thông tin về tệp .xml của [Content_Types], vui lòng tham khảo: A New Standard For Packaging Your Data Có một tệp ví dụ bên dưới Hình 13 của bài viết.

  • Mã này sử dụng phương pháp Stream.CopyTo trong .NET 4,0

+0

** tháng và năm ** nào cho _MDSN Magazine_? https://msdn.microsoft.com/en-us/magazine/ee310108.aspx – Kiquenet

18

NET 4.5 hoặc mới hơn cuối cùng đã được xây dựng trong khả năng để xử lý các file zip chung với lớp System.IO.Compression.ZipArchive (http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive%28v=vs.110%29.aspx) trong hệ thống lắp ráp .IO.Compression. Không cần thư viện của bên thứ ba.

string zipPath = @"c:\example\start.zip"; 
using (ZipArchive archive = ZipFile.OpenRead(zipPath)) 
{ 
    foreach (ZipArchiveEntry entry in archive.Entries) 
    { 
     Console.WriteLine(entry.FullName); 
    } 
} 
+5

Làm việc tốt và không có hộp bên thứ 3. Hãy chắc chắn thêm tham chiếu 'System.IO.Compression.dll' và' System.IO.Compression.FileSystem.dll'. – Matt