Gereksinimler ve Ön Hazırlık
Geliştirme ortamınızın güncel olması, modern C# özelliklerini kullanabilmeniz için elzemdir. Bu proje için aşağıdaki araçlara sahip olduğunuzdan emin olun:
- Visual Studio 2022 (Sürüm 17.12 veya üzeri)
- .NET 9.0 SDK
- WPF (Windows Presentation Foundation) iş yükü
- Temel C# dosya sistemi (System.IO) bilgisi
Projenizi oluştururken "WPF Application" şablonunu seçin ve hedef framework olarak .NET 9.0'ı işaretleyin. Proje yapısında "Core", "Services" ve "UI" katmanlarını ayırmanız, kodun sürdürülebilirliği açısından oldukça önemlidir.
Dosya İzleme ve Değişiklik Tespiti
Bir sürüm kontrol sisteminin kalbi, dosyaların değişip değişmediğini anlamaktır. Bunun için en performanslı yöntem, dosyanın SHA-256 hash değerini hesaplamaktır. Dosya içeriği değiştiğinde hash değeri de değişeceği için, sistemimiz bu değişikliği anında algılayacaktır.
using System.Security.Cryptography;
using System.IO;
public static string GetFileHash(string filePath)
{
using var sha256 = SHA256.Create();
using var stream = File.OpenRead(filePath);
var hash = sha256.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
Yukarıdaki kod, verilen dosya yolundaki içeriği okur ve benzersiz bir imza oluşturur. Bu imza, veritabanımızda veya yedekleme günlüğümüzde dosyanın "o anki sürümünü" temsil eder.
Dosya Yedekleme ve Sürümleme Mimarisi
Dosyaları yedeklerken, orijinal dosya adını ve zaman damgasını içeren bir klasörleme yapısı kullanmalıyız. Bu, aynı dosyanın farklı zamanlardaki sürümlerini çakışmadan saklamamıza olanak tanır.
public void BackupFile(string sourcePath, string backupFolder)
{
string fileName = Path.GetFileNameWithoutExtension(sourcePath);
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
string extension = Path.GetExtension(sourcePath);
string destinationPath = Path.Combine(backupFolder, $"{fileName}_{timestamp}{extension}");
File.Copy(sourcePath, destinationPath, true);
}
Bu metot, dosyayı hedef dizine zaman damgası ekleyerek kopyalar. Böylece "proje.cs" dosyası, yedek klasöründe "proje_20260520_143000.cs" şeklinde benzersiz bir isimle saklanır.
WPF Arayüzü ile Kullanıcı Etkileşimi
Kullanıcının yedekleme klasörünü seçebileceği ve işlemleri başlatabileceği basit bir arayüz tasarlamalıyız. WPF'in MVVM (Model-View-ViewModel) tasarım deseni, kod ve arayüzü birbirinden ayırmak için en iyi yaklaşımdır.
Bu XAML kodu, kullanıcıya basit bir etkileşim alanı sunar. Arka planda ise `System.Windows.Forms.FolderBrowserDialog` sınıfını kullanarak dizin seçimi yaptırabilirsiniz.
Sürüm Kontrol Yöntemlerinin Karşılaştırılması
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Hash Tabanlı | Çok güvenilir, içerik odaklı | Büyük dosyalarda işlem süresi |
| Zaman Damgalı | Hızlı, kolay uygulanabilir | İçerik değişmese de yedek alır |
| Fark (Delta) | Düşük depolama alanı | Karmaşık algoritma ihtiyacı |
Güvenlik ve Hata Yönetimi
Yedekleme işlemleri sırasında dosya erişim hataları (dosyanın başka bir program tarafından kullanılması gibi) kaçınılmazdır. Bu yüzden `try-catch` blokları ile işlemi sarmalamak kritik öneme sahiptir.
try
{
BackupFile(source, destination);
}
catch (IOException ex)
{
Logger.Log($"Hata oluştu: {ex.Message}");
}
catch (UnauthorizedAccessException)
{
Logger.Log("Dosyaya erişim yetkisi yok.");
}
Dikkat: Üretim ortamında yedekleme klasörlerini mutlaka şifreleyin ve erişim izinlerini kısıtlayın. Hassas kod dosyalarının yedeklendiği dizinlere yetkisiz erişim, veri sızıntısına yol açabilir.
Sıkça Sorulan Sorular
Neden Git yerine kendi sistemimi yapmalıyım?
Git, kaynak kod yönetimi için harikadır; ancak büyük medya dosyaları, veritabanı dosyaları veya çok özel otomatik yedekleme senaryoları için bazen kendi hafif çözümünüzü yazmak daha performanslı ve yönetilebilir olabilir.
Hash hesaplama performansı büyük dosyalarda nasıl iyileştirilir?
Dosyayı tamamen belleğe yüklemek yerine `FileStream` kullanarak parçalar halinde okumak (buffer kullanımı) bellek tüketimini ciddi oranda düşürür.
Yedeklenen dosyaları nasıl geri yüklerim?
Yedekleme klasörünüzdeki dosyaların isimlerini veya veritabanındaki kayıtlarını kullanarak, ilgili zaman damgasına sahip dosyayı orijinal konumuna kopyalayan bir "Geri Yükle" metodu yazmanız yeterlidir.
Bu sistem ağ sürücülerinde çalışır mı?
Evet, C# `System.IO` kütüphanesi UNC yollarını (\\sunucu\paylasim) destekler. Ancak ağ gecikmeleri için asenkron (async/await) programlama yapısını kullanmanız şarttır.
Veritabanı olarak ne kullanmalıyım?
Küçük ölçekli projeler için SQLite, hafif ve kurulum gerektirmeyen yapısıyla sürüm geçmişini tutmak için ideal bir seçenektir.
Otomatik Temizlik ve Sıkıştırma Servisi Uygulaması
Sürüm kontrol sisteminizin disk alanını verimli kullanması için, belirli bir yaşın üzerindeki yedekleri sıkıştırmanız veya tamamen silmeniz gerekir. Bu işlem, Retention Policy (Saklama Politikası) olarak adlandırılır. Aşağıdaki örnek, belirli bir klasördeki dosyaları kontrol ederek 30 günden eski olanları ZIP formatına dönüştüren bir yardımcı sınıfı göstermektedir.
Sıkıştırma ve Temizlik İçin Gerekli Yapı
Projenize System.IO.Compression kütüphanesini ekleyerek dosya arşivleme işlemlerini kolayca yönetebilirsiniz. Aşağıdaki kod bloğu, hedef dizindeki eski dosyaları tespit eder ve sıkıştırır.
using System;
using System.IO;
using System.IO.Compression;
public class BackupMaintenance
{
public static void ArchiveOldBackups(string backupPath, int daysOld)
{
DirectoryInfo di = new DirectoryInfo(backupPath);
foreach (FileInfo file in di.GetFiles())
{
if (file.CreationTime < DateTime.Now.AddDays(-daysOld) && file.Extension != ".zip")
{
string zipPath = file.FullName + ".zip";
using (ZipArchive archive = ZipFile.Open(zipPath, ZipArchiveMode.Create))
{
archive.CreateEntryFromFile(file.FullName, file.Name);
}
file.Delete(); // Orijinal dosyayı sil
}
}
}
}
Sistem Performansını İzleme ve Hata Ayıklama
Özel bir yedekleme sistemi geliştirirken, uygulamanın arka planda ne kadar kaynak tükettiğini takip etmek kritik öneme sahiptir. Özellikle büyük dosya dizinlerinde FileSystemWatcher kullanımı, CPU kullanımını anlık olarak artırabilir.
Performans İpuçları
- Asenkron İşlemler: Dosya kopyalama ve hash hesaplama işlemlerini
Task.Runile ana arayüz (UI) thread'inden ayırın. - Bellek Yönetimi: Çok büyük dosyaları okurken
File.ReadAllBytesyerineFileStreamkullanarak belleği (RAM) koruyun. - Loglama: Hataları takip etmek için basit bir metin dosyasına veya
EventLogsistemine kayıt yapın.
Aşağıdaki örnek, dosya okuma işlemini bellek dostu bir şekilde gerçekleştiren bir metot yapısını göstermektedir:
public async Task ProcessLargeFileAsync(string filePath)
{
using (FileStream sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[8192]; // 8KB tampon bellek
int bytesRead;
while ((bytesRead = await sourceStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
// İşleme mantığı burada yer alır (Örn: Hash hesaplama)
}
}
}
Hata Ayıklama Stratejisi
Sisteminizi canlıya almadan önce şu senaryoları mutlaka test edin:
- Kilitli Dosyalar: Başka bir program tarafından açık tutulan dosyalara erişim denemesi.
- İzin Hataları: Yedekleme klasörüne yazma yetkisinin olmaması durumu.
- Disk Doluluğu: Yedekleme diskinin dolması durumunda sistemin vereceği tepki.
İpucu: Hata ayıklama sürecinde try-catch bloklarını sadece genel hataları yakalamak için değil, dosya erişim hataları gibi spesifik durumlar için özelleştirin. Bu, sistemin neden durduğunu anlamanızı kolaylaştırır.
Sonuç
C# ile kendi sürüm kontrol ve yedekleme arayüzünüzü oluşturmak, hem dosya sistemi operasyonlarına hakimiyetinizi artırır hem de projeleriniz için özelleştirilmiş bir güvenlik katmanı sağlar. Bu rehberde öğrendiğiniz hash tabanlı kontrol ve dosya kopyalama teknikleri, daha gelişmiş özellikler (örneğin sıkıştırma, bulut senkronizasyonu veya arayüzde görselleştirme) eklemek için sağlam bir temeldir.
Yasal Uyarı: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Veri kaybını önlemek için yedekleme sisteminizi canlı ortama almadan önce kapsamlı testlerden geçirin. Yazılımsal hatalardan kaynaklanabilecek veri kayıplarından kullanıcı sorumludur.
Bir sonraki adım olarak, yedekleme klasöründeki dosyaları ZIP formatında sıkıştıran ve belirli bir süre sonra eski sürümleri otomatik silen (Retention Policy) bir temizlik servisi ekleyerek projenizi daha profesyonel hale getirebilirsiniz.


Yorumlar (0)
Yorum Yaz