Windows Dosya Önbelleğini Kullanmadan Bir Dosyayı Nasıl Kopyalarım
Windows içerisinde dosya yönetimi söz konusu olduğunda, işletim sisteminin dosya önbelleğinin performansı bozduğu durumlarla karşılaşabilirsiniz—özellikle büyük dosyalarla uğraşırken. Örneğin, büyük bir dosyayı bir USB bellekten veya bir sunucudan yerel makinenize kopyalamak sorunlu olabilir, çünkü Windows dosyayı önbelleğe alır, bu da verilerin değiştirilmesine neden olabilir ve işlemin tamamlanma süresini artırabilir.
Bu blog yazısında, dosya sistemini önbelleğe almadan dosya kopyalamayı nasıl çözebileceğimizi keşfedeceğiz, özellikle C# kullanarak.
Windows Dosya Sisteminin Önbelleğini Anlamak
Kodlama çözümüne geçmeden önce dosya sistemi önbelleğinin ne olduğunu anlamak önemlidir. Windows, dosya işlemlerini hızlandırmak için bir önbellek kullanır ve bu genellikle şunları içerir:
- Daha hızlı erişim için dosya verilerini bellekte saklama.
- USB bellekler gibi daha yavaş cihazlardan verileri alıp daha hızlı sistem belleğine aktarmaya çalışma.
Ancak, büyük dosyalar (2 GiB ya da daha fazla düşünün) ile bu önbellekleme süreci verimsizliklere neden olabilir, çünkü sistem mevcut belleği yönetmeye çalışır.
Çözüm: Win32 API Çağrılarını Kullanmak
Bu önbellekleme davranışını atlatmak için Windows, dosya işlemleri yaparken kullanabileceğiniz belirli bayraklar sağlar. Bu bayraklar şunlardır:
FILE_FLAG_WRITE_THROUGH
: Bu bayrak, dosyaya yazılanların doğrudan depolama aygıtına yazılmasını ve bellekte önbelleğe alınmamasını garanti eder.FILE_FLAG_NO_BUFFERING
: Bu bayrak, dosya için sistem önbelleğini devre dışı bırakır, yani tüm okuma ve yazma işlemleri doğrudan diske gider ve önbelleğe alınmaz.
Bu bayrakları C# kodunuzda kullanarak önbelleği kullanmadan doğrudan dosya kopyalamayı gerçekleştirebilirsiniz.
C# İle Adım Adım Uygulama
İşte C#’ta çözümün nasıl uygulanacağı:
-
Gerekli Kütüphaneleri Ekleyin: Dosya işlemleri ve interop hizmetleri için gerekli ad alanlarını eklediğinizden emin olun.
using System; using System.IO; using System.Runtime.InteropServices;
-
Yerel Yöntemleri Tanımlayın: Gerekli Win32 API işlevlerini tanımlamanız gerekir.
[DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr CreateFile( string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool ReadFile( IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool WriteFile( IntPtr hFile, byte[] lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool CloseHandle(IntPtr hObject);
-
Bayrakları Kullanmak: Dosya kopyalama fonksiyonunuzda dosya tanıtıcılarını oluşturmak için bayrakları kullanın.
public void CopyFileWithoutCache(string sourceFilePath, string destFilePath) { const uint GENERIC_READ = 0x80000000; const uint GENERIC_WRITE = 0x40000000; const uint OPEN_EXISTING = 3; const uint FILE_FLAG_WRITE_THROUGH = 0x80000000; const uint FILE_FLAG_NO_BUFFERING = 0x20000000; IntPtr sourceHandle = CreateFile(sourceFilePath, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, IntPtr.Zero); IntPtr destHandle = CreateFile(destFilePath, GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, IntPtr.Zero); // Dosya okuma ve yazma mantığını burada uygulayın... CloseHandle(sourceHandle); CloseHandle(destHandle); }
Sonuç
Yukarıda belirtilen adımlarla, Windows dosya sistemi önbelleğinin müdahalesi olmadan büyük dosyaları etkili bir şekilde kopyalayabilirsiniz. Bu yöntem, USB bellekler gibi yavaş aygıtlardan yüksek kapasiteli dosyalar aktarırken özellikle faydalıdır.
Daha fazla ayrıntı için FILE_FLAG_WRITE_THROUGH ve FILE_FLAG_NO_BUFFERING hakkında Microsoft belgelerine göz atın.
Bu bayrakları anlayarak ve kullanarak, dosya işlemlerinizin performansını önemli ölçüde artırabilirsiniz. İyi kodlamalar!