Zip ve Unzip İşlemleri

Zip dosyası oluşturma ve açma işlemleri (ASP.NET)

Hotmail'in, gelen epostaların ekini indirme seçeneklerinden birisi de zipleyerek indirme. Özellikle birden fazla ek varsa, bu özellik oldukça işe yarıyor.

Geçenlerde de bir projede buna benzer birşeye ihtiyacım oldu. Ben de birazcık araştırma yaptıktan sonra kullanıma hazır çok güzel bir DLL buldum.

Bu yazımızda bu DLL yi kullanmak için ne yapmamız gerekiyor, bunu anlatmaya çalışacağım.

Kullanacağımız DLL'nin adı DotNetZip Library.

Tabii ki uzmanlık ve ilgi alanım gereği daha çok ASP.NET üzerinden anlatmaya ve örnek göstermeye çalışacağım.

Sayfanın altında hazırladığım örnek projenin linkini ve ilgili linkleri bulabilirsiniz.


DotNetZip kullanımı kolay, hızlı ve ücretsiz bir ZIP dosyası aracıdır. Oldukça basit bir şekilde zip dosyası oluşturabiliyor ve var olan bir zip dosyasını açabiliyoruz.

Dahası, bu kütüphaneyi Silverlight, ASP.NET, Windows, WPF, WCF, .. kodunuzu nerede yazıyorsanız her yerde kullanabiliyorsunuz. :)

Şimdi örneklerle bu kütüphanenin kullanımını görelim:

using (ZipFile zip = new ZipFile())
 {
    // Bir dosya ekleme
    zip.AddFile("c:\\abc\\xyz\\123.png");

    // Bir klasörü komple ekleme
    zip.AddDirectory("c:\\abc\\Klasor1");

    // Bir dosya ekleme ve Zip içerisinde bulunacağı klasörü belirtme
     zip.AddFile("c:\\abc\\xyz\\345.png", "resimler");
     zip.AddFile("c:\\Dosyalar\\Sunu.docx", "dosyalar");

     // zip olarak kaydetme
     zip.Save("MyZipFile.zip");
 }

Zip dosyası oluşturma bu kadar basit.

Bu noktada, ASP.NET'te bu kodu çalıştırırken bir hususa dikkat etmek gerekiyor.

Dosya konumlarını mutlak olarak vermelisiniz. Dolayısıyla ASP.NET'te dosyayı eklemek için Server.MapPath() metodunu kullanmalıyız.

 using (ZipFile zip = new ZipFile())
 {
  zip.AddDirectory(Server.MapPath("~/upload/testklasoru"));
  zip.Save(Server.MapPath("~/upload/" + dosya));
 } 

~ : Root, kök klasör, ana klasör.

Oluşturulacak zip dosyasını bir stream'e de verebiliriz.

Aşağıdaki örnek, hiç fiziki dosya oluşturmadan direkt dosya indirme ekranını gösterecektir. (Hotmail'de olduğu gibi)

 using (ZipFile zip = new ZipFile())
 {
  string zipAdi = "deneme.zip";
  Response.Clear();
  Response.BufferOutput= false; // uzun dosyalar için
  Response.ContentType = "application/zip";
  Response.AddHeader("content-disposition", "filename=" + zipAdi);
  
  zip.AddDirectory(Server.MapPath("~/upload/testklasoru"));
  zip.Save(Response.OutputStream);
 } 
  Response.Close();

Dosya eklemenin bir başka yolu:

string[] dosyalar = { "ReadMe.txt", "c:\\data\\uyeler.csv", "c:\\reports\\rapor1.pdf"};
  using (ZipFile zip = new ZipFile())
  {
    zip.AddFiles(dosyalar);
    zip.Save("Arsiv.zip");
  }

* Directory.GetFiles() ve Directory.GetDirectories() methodlarının string[] tipinde bilgi döndürdüğünü hatırlayın !

Dosyayı, yorum ekleyerek zipleme:

using (ZipFile zip = new ZipFile())
  {
    ZipEntry e= zip.AddFile("Rapor.xslx");
    e.Comment = "Mayıs-Haziran gelir / gider tablosu.";
    zip.Save("Rapor.zip");
  }

Adını değiştirerek zipe ekleme:

using (ZipFile zip1 = new ZipFile())
  {
      string yeniAd = dosyaAdi + "-2";
      zip1.AddFile(dosyaAdi).FileName = yeniAd; 
      zip1.Save(zipAdi);
  }

Şifre ekleme:

using (ZipFile zip = new ZipFile())
{
    zip.Password= "123abc45@";
    zip.AddFile("Dosya1.txt");
    zip.AddFile("Dosya2.png");
    zip.Save("Yedek.zip");
}

Dosyaları farklı şifrelerle zipleme:

using (ZipFile zip = new ZipFile())
  {
    // Bu dosyanın şifresi yok
    zip.AddFile("Dosya1.txt"); 

    zip.Password= "123@";
    ZipEntry e = zip.AddFile("Dosya1.png");

    zip.Password= "!abc!";
    zip.AddFile("Dosya2.pdf");
    
    zip.Save("Yedek.zip");
  }

Buraya kadar ziplemeyi gösterdim.

Bir de ziplenmiş dosyayı açma örnekleri vereyim:

Teker teker açma:

using (ZipFile zip = ZipFile.Read(ZipDosyasi))
  {
    foreach (ZipEntry e in zip)
    {
      e.Extract(HedefKlasor);
    }
  }

Toplu olarak açma:

using (ZipFile zip = ZipFile.Read(ZipDosya))
  {
      zip.ExtractAll(HedefKlasor);    
  }

Üzerine yazarak açma:

using (ZipFile zip = ZipFile.Read(ZipDosyasi))
  {
    foreach (ZipEntry e in zip)
    {
      e.Extract(HedefKlasor, ExtractExistingFileAction.OverwriteSilently);
    }
  }

Stream'e açma:

using (ZipFile zip = ZipFile.Read(ZipDosyasi))
  {
 // zip içerisindeki dosyalardan birini seçiyoruz.
    ZipEntry e = zip["Rapor.doc"];
    e.Extract(Response.OutputStream);
  }

Şifre kullanarak açma:

using (ZipFile zip = ZipFile.Read(ZipDosyasi))
  {
    ZipEntry e = zip["Rapor.xls"];
    e.ExtractWithPassword(HedefKlasor, "sifre");
  }

Bir konuya da değinmeden geçemeyeceğim:

Zip dosyasının içerisindeki dosyaların seçimi için LINQ kullanabiliyorsunuz.

using (var zip = ZipFile.Read(ArchiveToRead))
{
    selection = from e in zip.Entries
        where e.UncompressedSize < 1024
        select e;

    foreach (var e in selection)
        Console.WriteLine(e.FileName);
}

Çok güzel, değil mi?


DLL'leri ve aşağıdaki linkleri inceleyerek başka başka özellikleri de sizler keşfedebilirsiniz.

Birkaçı:

  • WinZip uyumlu şifreleme
  • Sıkıştırma olmadan zipleme (mp3, jpg gibi dosyalar için)
  • Sıkıştırma oranı belirleme
  • Parçalı sıkıştırma (dosya büyüklüğüne göre dosya.z01, dosya,z02, ...)
  • Dosyalar için zaman damgası oluşturma
  • ? ve * joker karakterlerini kullanabilme
  • Seçiciler kullanarak dosyaları belirleme Örn: string selection = "(name = *.docx) AND (mtime > 2009-06-30)";
  • Rekürsif klasör işlemleri
  • Zip güncelleme (ekleme, çıkarma, vb.)
  • Exe formatında kaydetme

Hazırladığım örnek projeyi buradan indirebilirsiniz.

İlgili linkler:

Güle güle kullanın. :)

Not: Ben Ionic.Zip.dll dosyasını kullandım