2011-01-26 14 views
6

Şu anda .NET 2.0 altında SharpZipLib ile çalışıyorum ve bunun üzerinden tek bir sıkıştırılmış arşive tek bir dosyayı sıkıştırmam gerekiyor. Bunu yapmak için şu anda aşağıdaki kullanıyorum: Bu tam (imsi) olması gerektiği gibi çalışırSharpZipLib: Tek bir sıkıştırılmış dosyaya tek bir dosya sıkıştırılıyor

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

, ben küçük bir gotcha karşılaştım ancak test ederken. Benim geçici dizini (sıkıştırılmamış girdi dosyasını içeren yani dizin) aşağıdaki dosyaları içerdiğini Diyelim:

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 

Bütün .xml dosyaları sıkıştırılmış arşiv dahildir sıkıştırma çalıştırdığınızda. Bunun nedeni, CreateZip yöntemine iletilen son fileFilter parametresidir. Başlık altında SharpZipLib bir desen eşleştirmesi gerçekleştiriyor ve bu da xxx_ ve yyy_ ile öneklenen dosyaları seçiyor. Aynı zamanda, aynı zamanda da düzeltilen bir şeyi de alacağını farz ediyorum.

Soru şu ki, SharpZipLib ile tek bir dosyayı nasıl sıkıştırabilirim? O zaman belki de soru şu ki, fileFilter'u nasıl biçimlendirebilirim ki, maç sadece sıkıştırmak istediğim dosyayı alabilir ve başka hiçbir şey yapamaz.

Bir kenara göre, neden System.IO.Compression bir ZipStream sınıfı içermez? 'Sadece don,

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

Bir tarafınıza gelince: ZIPStream bir anlam ifade etmiyor çünkü ZIP birden fazla dosya tutabilen bir arşiv biçimidir. Sanırım okuma ve yazma ve postalama için tam bir API vermiş olabilirlerdi, ancak bu GZipStream'den çok daha fazla çaba sarfederdi. –

+0

Sadece tek bir dosyayı sıkıştırdığınız için, sadece bir kenara attığınız gibi, GZip sıkıştırmasını kullanmak istememenizin bir nedeni var mı? –

+0

Çok isterim, bunu birkaç satır kod ile yapabilirim. 'Destek' masamızın gzip karmaşıklıklarını kaldıramayacağı (bu ses alaycı oldu mu?;)) – MrEyes

cevap

5

Bu XY sorundur: (Hans Passant kabul cevap türeyen) Çözüm

Bu benim hayata sıkıştırma yöntemidir:

DÜZENLEME (Sadece GZipStream destekler) FastZip kullan. Kazaları önlemek için ilk örneği this web page numaralı telefondan takip edin.

+0

Bu çalışır, ancak sıkıştırılmış arşiv de tüm dizinleri de içerir. Arşiv sadece dosyayı kök düzeyinde ve başka hiçbir şey içermiyorsa daha iyi olurdu. – MrEyes

+1

string entryName = System.IO.Path.GetFileName (dosya adı); –