2008-10-08 27 views
19

Tôi biết có libraries out there for working with ZIP files. Và, bạn có thể thay thế use the functionality built into Windows for working ZIP files.Làm thế nào để sử dụng System.IO.Compression để đọc/ghi các tệp ZIP?

Nhưng, tôi tự hỏi liệu có ai đã tìm ra cách sử dụng các công cụ được tích hợp vào không gian tên System.IO.Compression trong .NET để đọc/ghi tệp ZIP không? Hoặc, là nó không thể chỉ sử dụng không gian tên này?

CẬP NHẬT: Tôi có vẻ như ai đó nhận xét rằng không gian tên System.IO.Packaging có thể hữu ích với điều này. Có ai biết chính xác làm thế nào để làm điều đó?

Trả lời

15

MSDN có đầy đủ examplehttp://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage.aspx sử dụng lớp ZipPackage. Yêu cầu .NET 3.5.

+5

Thực ra, không gian tên 'System.IO.Packaging' chứa các lớp để làm việc với các gói kiểu Bao bì mở. Bạn có thể sử dụng nó để tạo các tệp ZIP (nếu bạn không quan tâm đến một số tệp phụ sẽ được bao gồm trong ZIP của bạn), nhưng nó không thể được sử dụng để mở tệp * any * zip. Xem [dưới cùng của tài liệu lớp ZipPackage] (http://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage (v = vs.85) .aspx) để biết thêm thông tin (cộng đồng này không phải là có trong tài liệu .NET 4.0 nhưng vẫn hợp lệ). – larsmoa

0

Có, tôi đã sử dụng nó trong quá khứ. Tôi đã xếp loại DataSet một lần để tự hỗ trợ cho một tệp (thông qua phương thức ReadXML/WriteXML). Là một phần thưởng thêm, tôi quyết định cho phép nó được, tùy chọn, nén nếu muốn (điều này, như tất cả các bạn đã biết, là cực kỳ hiệu quả với dữ liệu văn bản như XML).

Tôi đã sử dụng lớp GZipStream (đó là sự hiểu biết của tôi tại thời điểm DeflateStream liên quan chỉ đơn thuần là GZip không có thông tin tiêu đề hoặc một số như vậy — Tôi chắc chắn ai đó có thể sửa lỗi này). Nó hoạt động khá đơn giản bởi sự ủng hộ của heo trên đầu trang của một luồng khác và do đó bạn sử dụng GZipStream ở vị trí của nó. Trong trường hợp của tôi, đó là sự ủng hộ của heo trên một FileStream.

Cho một MemoryStream để được lấp đầy với đầu ra của myDataSet.WriteXML(), tôi đã làm một cái gì đó như sau:

if (CompressData) 
{ 
    // Write to memory 
    mStream = new MemoryStream(); 
    Save(mStream); 
    mStream.Seek(0, SeekOrigin.Begin); 

    // Filter that through a GZipStream and then to file 
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName + ".gz"), 
          FileMode.OpenOrCreate); 
    zipStream = new GZipStream(fStream, CompressionMode.Compress, true); 

    Pump(mStream, zipStream); 
} 
else 
{ 
    // Write straight to file 
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName), 
          FileMode.OpenOrCreate); 
    Save(fStream); 
} 

đâu Save()Pump() là phương pháp đơn giản như sau:

private void Pump(Stream input, Stream output) 
{ 
    int n; 
    byte[] bytes = new byte[4096]; // 4KiB at a time 

    while ((n = input.Read(bytes, 0, bytes.Length)) != 0) 
    { 
     output.Write(bytes, 0, n); 
    } 
} 

public void Save(Stream stream) 
{ 
    AcceptChanges(); 

    WriteXml(stream, XmlWriteMode.WriteSchema); 
} 
+0

Giải pháp của bạn không đọc hoặc ghi sang định dạng tệp ZIP, mà chỉ đơn giản là nén thô thô, hoặc GZip mở rộng đầu trang chân trang đơn giản xung quanh nén deflate. –

+0

+1 câu trả lời của bạn có thể không tạo tệp ZIP, nhưng nó hiển thị cách sử dụng System.IO.Compression, điều tuyệt vời để nén tệp trong SSIS nơi bạn bị giới hạn ở .NET 2.0 và khó sử dụng thư viện bên ngoài. – bstoney

6

Bạn sẽ muốn sử dụng thư viện của bên thứ ba, chẳng hạn như http://www.codeplex.com/DotNetZip, thay vì cố sử dụng GZipStream hoặc DeflateStream để đọc tệp zip.

*** Các lớp dòng trong .NET có thể cho phép bạn đọc hoặc ghi các luồng byte đã nén. Các lớp này KHÔNG đọc hoặc ghi các tệp zip. Tệp zip là dữ liệu được nén được bao quanh bởi "phong bì" hoặc tiêu đề. Hãy coi nó là siêu dữ liệu - nó bao gồm tên của tệp, dấu thời gian, CRC và một loạt các nội dung khác. ** Các lớp luồng chỉ tạo ra luồng dữ liệu nén và không biết cách tạo hoặc tiêu thụ siêu dữ liệu, được mô tả trong đặc tả định dạng PKZip được PKWare duy trì.

Thư viện của bên thứ ba như DotNetZip xử lý siêu dữ liệu trong lưu trữ ZIP. Họ có thể hoặc không thể sử dụng lớp System.IO.Compression.DeflateStream() để tạo ra luồng dữ liệu được nén của các byte. Trong các bản phát hành trước, ví dụ, DotNetZip đã sử dụng DeflateStream tích hợp sẵn. Kể từ v1.7, DotNetZip bao gồm DeflateStream của riêng nó mà là hiệu quả hơn so với một trong những vận chuyển trong các.NET Framework. Như một lợi ích bổ sung, các DeflateStream nhúng trong DotNetZip cho phép DotNetZip được sử dụng trên .NET Compact Framework 2.0, mà thiếu một System.IO.Compression.DeflateStream. (nó đã được thêm vào trong Compact Framework 3.5)

Có một diễn đàn tốt trên trang DotNetZip nếu bạn có thêm câu hỏi. Ví dụ C# mã:

try 
    { 
     using (ZipFile zip = new ZipFile()) 
     { 
      zip.AddDirectory(DirectoryToZip); // recurses subdirs 
      zip.Save(Filename); 
     } 
    } 
    catch (System.Exception ex1) 
    { 
     System.Console.Error.WriteLine("exception: " + ex1); 
    } 
0
public static void zIpDatabseFile(string srcPath, string destPath) 
    {//This is for Zip a File 
     using (var source = new FileStream(srcPath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     using (var dest = new FileStream(destPath, FileMode.OpenOrCreate, FileAccess.Write)) 
     using (var zip = new GZipStream(dest, CompressionMode.Compress)) 
     { 
      source.CopyTo(zip); 
     } 
    } 
    public static void uNzIpDatabaseFile(string SrcPath, string DestPath) 
    {// This is for unzip a files. 
     using (var source = new FileStream(SrcPath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     using (var dest = new FileStream(DestPath, FileMode.OpenOrCreate, FileAccess.Write)) 
     using (var zip = new GZipStream(source, CompressionMode.Decompress)) 
     { 
      zip.CopyTo(dest); 
     } 
    } 
5

Kể từ .NET 4.5, Microsoft đã cung cấp lớp ZipArchive đến namespace System.IO.Compression. Tuy nhiên, không giống như các lớp khác trong không gian tên đó, như luồng GZipStreamDeflate, số ZipArchiveyêu cầu tham chiếu đến hội đồng System.IO.Compression.dll.

Nó khá đơn giản để sử dụng, và liên kết ở trên để MSDN cung cấp một số ví dụ tốt.

Bên cạnh đó, Microsoft đã tạo ra Microsoft Compression NuGet package, có thêm hỗ trợ cho ZipArchive và các lớp học liên quan đến Windows Phone 8 và Thư viện di động lớp khác

3

Một chủ đề cũ, tôi biết, nhưng tôi muốn chỉ ra rằng. NET 4.5 bổ sung các cải tiến mở rộng cho system.io.compression. Bây giờ nó có thể thao tác các tệp .zip khá tốt, thậm chí xuống để hiển thị từng tệp riêng lẻ trong vùng nén dưới dạng luồng có khả năng hoặc đọc và ghi mà không cần bước giải nén và nén tệp.

Các vấn đề liên quan