C# İle Dosya Sıkıştırma Aracı Nasıl Yapılır?

C# İle Dosya Sıkıştırma Aracı Nasıl Yapılır?
C# İle Dosya Sıkıştırma Aracı Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Uygulamamızı geliştirmek için güncel bir .NET ortamına ihtiyacımız var. 2026 yılı standartlarında .NET 8 veya üzeri sürümleri kullanmanızı öneririm. İşletim sisteminizde Visual Studio 2022 veya VS Code yüklü olmalıdır.

  • .NET SDK: En güncel sürümün yüklü olduğundan emin olun.
  • System.IO.Compression: Dosya sıkıştırma işlemleri için temel kütüphanemizdir.
  • System.IO.Compression.ZipFile: Üst düzey sıkıştırma ve arşivleme fonksiyonlarını içerir.

Projenizi oluşturmak için terminal ekranında şu komutu çalıştırabilirsiniz:

dotnet new console -n DosyaSikistirmaAraci
cd DosyaSikistirmaAraci
dotnet add package System.IO.Compression.ZipFile

Bu komutlar, projenizin temel iskeletini oluşturacak ve gerekli NuGet paketini projenize dahil edecektir.

Adım Adım Tek Bir Dosyayı Sıkıştırma

İlk aşamada, tek bir dosyayı hedef klasöre ZIP formatında sıkıştırmayı öğreneceğiz. Bunun için ZipFile.CreateFromDirectory veya ZipFile.Open yöntemlerini kullanabiliriz. Ancak tek dosya için en pratik yol, bir ZIP arşivi oluşturup içine dosya eklemektir.

using System.IO.Compression;

string kaynakDosya = "belge.txt";
string hedefZip = "arsiv.zip";

using (ZipArchive zip = ZipFile.Open(hedefZip, ZipArchiveMode.Create))
{
    zip.CreateEntryFromFile(kaynakDosya, Path.GetFileName(kaynakDosya));
}
Console.WriteLine("Dosya başarıyla sıkıştırıldı.");

Burada ZipArchiveMode.Create parametresi, eğer dosya zaten varsa üzerine yazılacağını veya yeni bir dosya oluşturulacağını belirtir. CreateEntryFromFile metodu ise fiziksel dosyayı arşivin içine kopyalar.

Tüm Klasörü Arşivleme ve Performans Yönetimi

Büyük projelerde tek tek dosya eklemek yerine tüm dizini sıkıştırmak daha verimlidir. .NET, ZipFile.CreateFromDirectory metodu ile bu işlemi tek satırda yapmamıza olanak tanır.

using System.IO.Compression;

string kaynakKlasor = @"C:\Proje\Veriler";
string ciktiZip = @"C:\Proje\Yedekler\veriler.zip";

ZipFile.CreateFromDirectory(kaynakKlasor, ciktiZip, CompressionLevel.Optimal, false);
Console.WriteLine("Klasör başarıyla sıkıştırıldı.");

CompressionLevel.Optimal, işlemci gücü ile dosya boyutu arasında en iyi dengeyi kurar. Eğer hız sizin için daha önemliyse CompressionLevel.Fastest seçeneğini tercih edebilirsiniz.

Arşiv İçeriğini Listeleme ve Okuma

Sıkıştırdığınız bir dosyanın içeriğini açmadan görmek, hata ayıklama ve kullanıcı arayüzleri için önemlidir. Aşağıdaki örnekte, bir ZIP dosyasının içindeki dosyaları nasıl listeleyebileceğinizi görebilirsiniz.

using System.IO.Compression;

using (ZipArchive arşiviOku = ZipFile.OpenRead("arsiv.zip"))
{
    foreach (ZipArchiveEntry entry in arşiviOku.Entries)
    {
        Console.WriteLine($"Dosya Adı: {entry.FullName} | Boyut: {entry.Length} byte");
    }
}

Bu kod bloğu, arşivin içeriğini belleğe yüklemeden okur, bu da büyük dosyalarla çalışırken bellek tasarrufu sağlar.

Güvenli Dosya Çıkarma (Extraction) İşlemleri

Sıkıştırılmış bir dosyayı dışarı aktarırken "Zip Slip" saldırılarına karşı dikkatli olmalısınız. Kötü niyetli dosyalar, arşiv dışına çıkmaya çalışan yollar içerebilir. Her zaman hedef dizini doğrulamalısınız.

using System.IO.Compression;

string zipDosyasi = "arsiv.zip";
string ciktiKlasoru = @"C:\Cikartilanlar";

Directory.CreateDirectory(ciktiKlasoru);

using (ZipArchive arşiviAc = ZipFile.OpenRead(zipDosyasi))
{
    foreach (ZipArchiveEntry entry in arşiviAc.Entries)
    {
        string tamYol = Path.GetFullPath(Path.Combine(ciktiKlasoru, entry.FullName));
        
        if (tamYol.StartsWith(Path.GetFullPath(ciktiKlasoru), StringComparison.Ordinal))
        {
            entry.ExtractToFile(tamYol, true);
        }
    }
}
Kritik Güvenlik Uyarısı: Arşivden dosya çıkarırken, dosya yollarının hedef dizinin dışında olup olmadığını mutlaka kontrol edin. Aksi takdirde, saldırganlar sistem dosyalarınızın üzerine yazabilir.

Sıkıştırma Yöntemlerinin Karşılaştırılması

Aşağıdaki tablo, C# ile kullanabileceğiniz farklı sıkıştırma yaklaşımlarının temel özelliklerini özetlemektedir:

Yöntem Avantajı Dezavantajı
ZipFile.CreateFromDirectory Hızlı ve kolay kullanım Düşük özelleştirme
ZipArchive (Manual) Tam kontrol, dosya bazlı işlem Daha karmaşık kod yapısı
GZipStream Tek dosya için çok verimli Klasör yapısını desteklemez

Sıkça Sorulan Sorular

Sıkıştırma işlemi sırasında "Dosya kullanımda" hatası alıyorum, ne yapmalıyım?

Bu hata genellikle dosyanın başka bir işlem tarafından açık tutulmasından kaynaklanır. using bloklarını kullanarak dosya akışlarını (stream) işiniz bittiğinde otomatik olarak kapatmayı unutmayın.

Şifreli ZIP dosyaları oluşturabilir miyim?

Standart System.IO.Compression kütüphanesi şifreleme (AES vb.) desteklemez. Şifreli arşivler için DotNetZip veya SharpZipLib gibi üçüncü taraf kütüphaneleri incelemeniz gerekir.

Büyük boyutlu dosyalarda bellek sorunu yaşar mıyım?

ZipArchive sınıfı akış tabanlı (stream-based) çalışır. Dosyaları doğrudan belleğe yüklemek yerine stream üzerinden işlerseniz, çok büyük dosyalarda bile düşük RAM kullanımı sağlarsınız.

Sıkıştırma seviyesini nasıl ayarlarım?

CompressionLevel enum yapısını kullanarak Optimal, Fastest veya NoCompression seçeneklerinden birini tercih edebilirsiniz.

Bu araç web projelerinde kullanılabilir mi?

Evet, ASP.NET Core projelerinde kullanıcıya dosya indirtmeden önce dinamik olarak ZIP oluşturmak için bu yöntemleri güvenle kullanabilirsiniz.

Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce hata yönetimi (try-catch blokları) ve dosya izinleri kontrollerini eklediğinizden emin olun.

İleri Seviye Performans Optimizasyonu ve Asenkron İşlemler

Büyük veri setleri veya binlerce küçük dosyadan oluşan arşivleme işlemlerinde, ana iş parçacığının (UI thread) donmaması için async/await yapısını kullanmak kritik öneme sahiptir. System.IO.Compression kütüphanesi, I/O yoğunluklu işlemler için asenkron metodlar sunar.

Aşağıdaki örnek, büyük bir klasörü asenkron olarak sıkıştırırken uygulamanın yanıt verebilirliğini nasıl koruyacağınızı gösterir:

public async Task CompressDirectoryAsync(string sourceDir, string zipPath)
{
    await Task.Run(() =>
    {
        if (File.Exists(zipPath)) File.Delete(zipPath);
        ZipFile.CreateFromDirectory(sourceDir, zipPath, CompressionLevel.Fastest, false);
    });
}

İpucu: CompressionLevel.Fastest seçeneği, CPU kullanımını optimize ederken dosya boyutunda küçük bir artışa neden olabilir. Eğer disk alanınız kısıtlıysa CompressionLevel.Optimal tercih edilmelidir.

Alternatif Kütüphane: DotNetZip Kullanımı

.NET'in yerleşik kütüphanesi çoğu senaryo için yeterli olsa da, gelişmiş özellikler (örneğin; arşiv içindeki belirli bir dosyayı silme, şifreleme algoritmaları veya gelişmiş ilerleme raporlama) gerektiğinde DotNetZip (Ionic.Zip) kütüphanesi endüstri standardı kabul edilir.

DotNetZip ile İlerleme Takibi

Kullanıcıya işlemin yüzde kaçının tamamlandığını göstermek, profesyonel bir araç geliştirmenin olmazsa olmazıdır. DotNetZip, SaveProgress eventi sayesinde bunu kolaylaştırır:

using (ZipFile zip = new ZipFile())
{
    zip.AddDirectory(@"C:\Dosyalarim");
    zip.SaveProgress += (sender, e) =>
    {
        if (e.EventType == ZipProgressEventType.Saving_EntryBytesRead)
        {
            double percent = (100.0 * e.BytesTransferred) / e.TotalBytesToTransfer;
            Console.WriteLine($"İlerleme: %{percent:F2}");
        }
    };
    zip.Save("Arsiv.zip");
}

Neden Alternatif Kütüphanelere İhtiyaç Duyulur?

  • Dosya Güncelleme: Yerleşik kütüphane arşivi yeniden oluşturmayı gerektirirken, DotNetZip mevcut bir arşivin içine dosya ekleyebilir veya silebilir.
  • Kod Sayfası Desteği: Eski sistemlerden gelen Türkçe karakterli dosya isimlerinde yaşanan kodlama sorunlarını (encoding) yönetmek daha kolaydır.
  • Gelişmiş Şifreleme: AES-256 gibi daha güvenli şifreleme standartlarına doğrudan destek sağlar.

Dağıtım ve Hata Ayıklama (Deployment)

Geliştirdiğiniz aracı son kullanıcıya ulaştırırken, uygulamanın çalışacağı ortamda .NET Runtime'ın kurulu olduğundan emin olmalısınız. Ayrıca, dosya izinleri ile ilgili hataları yakalamak için aşağıdaki hata ayıklama şablonunu kullanmanız önerilir:

try 
{
    ZipFile.CreateFromDirectory(source, destination);
}
catch (UnauthorizedAccessException) 
{
    // Kullanıcının klasöre erişim izni yok
    Logger.Log("Erişim reddedildi. Lütfen yönetici haklarını kontrol edin.");
}
catch (IOException ex) 
{
    // Dosya başka bir işlem tarafından kullanılıyor
    Logger.Log($"Dosya kilitli: {ex.Message}");
}

Sonuç

C# ile dosya sıkıştırma aracı geliştirmek, .NET'in sunduğu güçlü kütüphaneler sayesinde oldukça verimli bir süreçtir. Bu rehberde, tek dosya sıkıştırmadan, güvenli dosya çıkarma işlemlerine kadar temel yetenekleri kazandınız. Bir sonraki adım olarak, bu mantığı bir Windows Forms veya WPF arayüzü ile birleştirerek kullanıcı dostu bir masaüstü uygulamasına dönüştürebilirsiniz. Başarılar dilerim.

Bu yazıya tepkinizi paylaşın:
Zeynep Kaya

Adım adım rehber hazırlama ve kullanıcı deneyimi odaklı içerik mimarisi konusunda yetkinim. Okuyucuların sorunlarını hızlı çözen, net ve uygulanabilir metinler üretmeyi seviyorum.

Yorumlar (0)

Yorum Yaz