2011-01-26 40 views
6

Tôi hiện đang làm việc với SharpZipLib trong .NET 2.0 và thông qua điều này, tôi cần nén một tệp duy nhất vào một tệp nén duy nhất. Để thực hiện việc này, tôi hiện đang sử dụng các thông tin sau:SharpZipLib: Nén một tệp đơn thành một tệp nén

string tempFilePath = @"C:\Users\Username\AppData\Local\Temp\tmp9AE0.tmp.xml"; 
string archiveFilePath = @"C:\Archive\Archive_[UTC TIMESTAMP].zip"; 

FileInfo inFileInfo = new FileInfo(tempFilePath); 
ICSharpCode.SharpZipLib.Zip.FastZip fZip = new ICSharpCode.SharpZipLib.Zip.FastZip(); 
fZip.CreateZip(archiveFilePath, inFileInfo.Directory.FullName, false, inFileInfo.Name); 

Điều này hoạt động chính xác (ish) như cần, tuy nhiên trong khi thử nghiệm tôi đã gặp phải một dấu hiệu nhỏ. Cho phép nói rằng thư mục tạm của tôi (ví dụ: thư mục chứa các tập tin đầu vào không nén) chứa các tập tin sau đây:

tmp9AE0.tmp.xml //The input file I want to compress 
xxx_tmp9AE0.tmp.xml // Some other file 
yyy_tmp9AE0.tmp.xml // Some other file 
wibble.dat // Some other file 

Khi tôi chạy nén tất cả các .xml tập tin được bao gồm trong tài liệu nén. Lý do là vì thông số fileFilter cuối cùng được chuyển đến phương thức CreateZip. Dưới mui xe, SharpZipLib đang thực hiện đối sánh mẫu và điều này cũng chọn các tệp có tiền tố là xxx_yyy_. Tôi cho rằng nó cũng sẽ nhận bất cứ thứ gì được postfix.

Vì vậy, câu hỏi đặt ra là làm thế nào tôi có thể nén một tệp bằng SharpZipLib? Sau đó, một lần nữa có lẽ câu hỏi là làm thế nào tôi có thể định dạng rằng fileFilter để các trận đấu chỉ có thể chọn lên các tập tin tôi muốn nén và không có gì khác.

Ngoài ra, có lý do nào để giải thích tại sao System.IO.Compression không bao gồm lớp học ZipStream không? (Nó chỉ hỗ trợ GZipStream)

EDIT: Giải pháp (Xuất phát từ câu trả lời chấp nhận từ Hans passant)

Đây là phương pháp nén tôi thực hiện:

private static void CompressFile(string inputPath, string outputPath) 
{ 
    FileInfo outFileInfo = new FileInfo(outputPath); 
    FileInfo inFileInfo = new FileInfo(inputPath); 

    // Create the output directory if it does not exist 
    if (!Directory.Exists(outFileInfo.Directory.FullName)) 
    { 
     Directory.CreateDirectory(outFileInfo.Directory.FullName); 
    } 

    // Compress 
    using (FileStream fsOut = File.Create(outputPath)) 
    { 
     using (ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipStream = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream(fsOut)) 
     { 
      zipStream.SetLevel(3); 

      ICSharpCode.SharpZipLib.Zip.ZipEntry newEntry = new ICSharpCode.SharpZipLib.Zip.ZipEntry(inFileInfo.Name); 
      newEntry.DateTime = DateTime.UtcNow; 
      zipStream.PutNextEntry(newEntry); 

      byte[] buffer = new byte[4096]; 
      using (FileStream streamReader = File.OpenRead(inputPath)) 
      { 
       ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(streamReader, zipStream, buffer); 
      } 

      zipStream.CloseEntry(); 
      zipStream.IsStreamOwner = true; 
      zipStream.Close(); 
     } 
    } 
} 
+2

Đối với bạn sang một bên: ZipStream sẽ không có ý nghĩa nhiều, vì ZIP là một định dạng lưu trữ có thể chứa nhiều hơn một tệp. Tôi cho rằng họ có thể đã cung cấp một API đầy đủ để đọc và viết và các tệp ZIP, nhưng điều đó rõ ràng sẽ có nhiều nỗ lực hơn GZipStream. –

+0

Là một phần của riêng tôi, vì bạn chỉ nén một tệp duy nhất, có một lý do tại sao bạn không muốn chỉ sử dụng nén GZip, như bạn lưu ý, có hỗ trợ trong khung công tác không? –

+0

Tôi rất thích, tôi có thể làm điều này với một vài dòng mã. Nó phải được nén như bàn "hỗ trợ" của chúng tôi không thể xử lý các phức tạp của gzip (đã làm âm thanh châm biếm ??;)) – MrEyes

Trả lời

5

Đây là một vấn đề XY, chỉ don' t sử dụng FastZip. Thực hiện theo ví dụ đầu tiên trên this web page để tránh tai nạn.

+0

Đó là công trình, tuy nhiên các kho lưu trữ nén bao gồm tất cả các thư mục là tốt. Sẽ tốt hơn nếu lưu trữ chỉ chứa tệp ở cấp cơ sở và không có gì khác. – MrEyes

+1

string entryName = System.IO.Path.GetFileName (tên tệp); –

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