C# programında "The process cannot access the file because it is being used by another process" hatası, bir dosya açık tutulurken ona ikinci bir erişim denendiğinde fırlatılan IOException'dır. Çoğunlukla açık kalmış bir FileStream, eksik bırakılmış bir using ya da dosyayı kilitleyen başka bir işlem yüzünden ortaya çıkar. Çözüme akışların yaşam döngüsünü ve erişim paylaşımını kontrol ederek başla: dosya nerede açılıyor, nerede kapanıyor ve açıkken kimlere hangi erişim izni veriliyor?
Bu hata ne anlıyor ve önce nereye bakmalısın?
Hata mesajı, dosyaya erişmek istediğin anda onun başka bir yerde açık olduğunu söyler. Mesaj kodun hangi satırında dosyanın açık kaldığını göstermez, yalnızca erişimin reddedildiğini bildirir. Bu yüzden teşhis, dosyayı açan her noktayı bulmakla başlar.
Dört kavramı bir kapı benzetmesiyle bağlayabilirsin. FileStream dosyaya açılan kapıdır. using, bloğun sonunda bu kapıyı senin yerine kapatır. Dispose kapatma işini yapan yöntemdir; using bloğu bittiğinde arka planda onu çağırır. FileShare ise kapı açıkken içeri başka kimlerin, hangi erişimle (yalnız okuma, okuma ve yazma gibi) girebileceğini belirleyen ayardır. Kapıyı kapatmayı unutursan ya da kapıyı açan taraf ile içeri girmek isteyen taraf FileShare konusunda anlaşamazsan bu hatayı alırsın.
C# bilginin hangi seviyede olduğunu ölçmek istersen ücretsiz bilgi testleri merkezi işine yarayabilir.
Senaryo 1: Akışı kapatmamak

En yaygın neden budur: dosyaya yazan bir akış açılır ama kapatılmaz, sonra aynı dosya tekrar açılmaya çalışılır. Önce hatayı üreten kodu görelim:
var yazici = new StreamWriter("log.txt");
yazici.WriteLine("Ilk kayit");
// Close veya Dispose cagrilmadi
string icerik = File.ReadAllText("log.txt"); // burada hata alirsin
Console.WriteLine(icerik);
Windows'ta beklenen çıktı şuna benzer bir istisnadır:
System.IO.IOException: The process cannot access the file '...log.txt' because it is being used by another process.
Aynı kodun using ile düzeltilmiş hâli:
using (var yazici = new StreamWriter("log.txt"))
{
yazici.WriteLine("Ilk kayit");
} // blok biterken Dispose otomatik cagrilir
Console.WriteLine(File.ReadAllText("log.txt"));
Beklenen çıktı:
Ilk kayit
using, blok içinde istisna oluşsa bile Dispose'u çağırır. StreamWriter'ı kapatmak da altındaki akışı kapatır. Bu yüzden dosya yazma bittiği anda serbest kalır.
Teşhis için üç adım izle:
- Dosyayı açan satırı bul (
new StreamWriter,new FileStream,File.Opengibi). - O akışın nerede kapandığını ara; kapanış yoksa sorunu bulmuşsun demektir.
- Kapanışın garantili olup olmadığına bak:
usingya datry/finallyiçindeDisposevar mı? Araya bir istisna girerse kapanış atlanıyor olabilir.
Senaryo 2: Aynı dosyayı program içinde ikinci kez açmak
Bazen kapatmayı unutmazsın ama dosya hâlâ yazma için açıktır ve başka bir kod parçası aynı dosyayı okumaya ya da kopyalamaya çalışır. Örneğin log dosyasına yazan bir StreamWriter açıkken File.Copy("log.txt", "yedek.txt") ya da File.ReadAllText("log.txt") çağrılırsa aynı IOException fırlatılabilir. Burada dosya iki farklı erişimle aynı anda istenir ve paylaşım ayarları bu birlikteliğe izin vermez.
En sağlam çözüm erişim sırasını düzeltmektir: önce yazmayı bitir, using bloğunu kapat, sonra kopyala ya da oku. Teşhis için aynı dosya yoluna kaç yerde eriştiğini ara, çağrıları sırayla bir kâğıda yaz ve o anda açık bir akış kalıp kalmadığına bak.
Sıra değişemiyorsa FileShare devreye girer. Yazan akışı FileShare.Read ile açarsan başkalarının okumasına izin vermiş olursun. Okuyan taraf da kendi paylaşım isteğini uyumlu bildirmelidir; paylaşım ayarları her iki tarafta birbiriyle uyuşmalıdır:
using (var yazan = new FileStream("log.txt", FileMode.Create,
FileAccess.Write, FileShare.Read))
using (var yazici = new StreamWriter(yazan))
{
yazici.WriteLine("Ilk kayit");
yazici.Flush(); // veriyi dosyaya gonder
using (var okuyan = new FileStream("log.txt", FileMode.Open,
FileAccess.Read, FileShare.ReadWrite))
using (var okuyucu = new StreamReader(okuyan))
{
Console.WriteLine(okuyucu.ReadLine());
}
}
Beklenen çıktı:
Ilk kayit
Okuyan akışın FileShare.ReadWrite istemesinin nedeni, dosyada zaten yazan bir akışın açık olmasıdır; okuyucu bu mevcut yazma erişimini kabul etmezse yine hata alırsın.
Ama FileShare'i gevşetmeyi son çare olarak düşün. Okuyucu dosyayı yazma yarım kalmışken görebilir, yani eksik ya da tutarsız veri okuyabilirsin. Önce erişim sırasını düzeltmeyi dene, paylaşımı ancak gerçekten eşzamanlı erişim gerektiğinde aç.
Senaryo 3: Dosyayı başka bir uygulama açık tutuyorsa nasıl anlarsın?
Kodun doğru olsa bile dosya senin programının dışındaki bir uygulama tarafından açık tutuluyor olabilir. Excel, bir metin düzenleyici, yedekleme yazılımı ya da antivirüs taraması bu tür örneklerdir. Kilit davranışı işletim sistemine göre değişebileceği için aynı kod bir bilgisayarda hata verirken başka birinde çalışabilir. Teşhisi tahminle değil, sırayla eleyerek yap:
- Dosyayı açık tutabilecek uygulamaları kapat. Dosyayı Excel'de ya da bir metin düzenleyicide açtıysan önce onu kapat, sonra programını yeniden çalıştır. Hata kayboluyorsa kilidi o uygulama tutuyordur.
- Kendi programının önceki çalıştırmasına bak. Konsol penceresi kapanmamış ya da program arka planda çalışmaya devam ediyor olabilir. Görev yöneticisinde programının adını arayıp varsa sonlandır.
- IDE'deki hata ayıklama oturumunu bitir. Hata ayıklayıcıda durdurduğun program dosyayı açık bırakmış olabilir. Oturumu tamamen sonlandırıp tekrar başlat.
- Dosyanın konumuna bak. Dosya bir bulut senkronizasyon klasöründeyse eşitleme istemcisi dosyayı o sırada okuyor olabilir. Dosyayı senkronize edilmeyen bir klasöre taşıyıp dene.
- Hâlâ çözülmediyse kilidi tutan işlemi araştır. Dosyayı hangi işlemin tuttuğunu gösteren araçlar vardır. İşletim sisteminin sunduğu kaynak izleme araçlarından birini kullanabilirsin.
Dosya kapatılınca hata kayboluyorsa sorun kodunda değil, dosyayı paylaşan uygulamadadır. Dışarıdaki uygulamayı sen kontrol edemediğinden çözüm genellikle dosyayı o uygulama kapalıyken işlemek ya da başka bir klasörde çalışmaktır.
Üç senaryoyu tablo ile nasıl ayırt edersin?

Üç senaryoda da hata mesajı aynıdır, bu yüzden belirtiye ve ilk teşhis adımına bakmak gerekir.
| Senaryo | Tipik belirti | İlk teşhis adımı | Çözüm yönü |
|---|---|---|---|
| Akışı kapatmamak | Hata, aynı programı ikinci kez çalıştırınca ya da döngünün ikinci turunda çıkar | Kodda FileStream, StreamReader ve StreamWriter nesnelerinin using içinde olup olmadığına bak | Akışı using ile sar, işin biter bitmez kapansın |
| Aynı dosyayı program içinde ikinci kez açmak (kopyalama ve yazma akışı dahil) | Program tek başına çalışırken ve hiçbir uygulama açık değilken bile hata verir | Aynı yola birden fazla açma ya da kopyalama çağrısı yapılıp yapılmadığını izle | Dosyayı tek akıştan işle, ikinci açmadan önce birinciyi kapat ya da paylaşım modunu bilinçli seç |
| Başka uygulamanın dosyayı açık tutması | Dışarıdaki uygulama kapatılınca hata kaybolur | Dosyayı kullanan uygulamaları, önceki çalıştırmayı ve senkronizasyon klasörünü kontrol et | Kilidi bırakacak uygulamayı kapat ya da dosyayı başka bir konumda işle |
Önce kendi kodundan şüphelen, sonra dışarıya doğru ilerle. Programı tek başına, başka hiçbir uygulama açıkken denediğinde de hata sürüyorsa ilk iki senaryoya odaklan. Hata yalnızca dosya başka bir yerde açıkken çıkıyorsa üçüncü senaryo öne geçer.
IOException'ı yakalarken hatayı sessizce yutma
IOException sınıfı System.IO ad alanındadır ve dosya paylaşım ihlali gibi giriş çıkış hatalarında fırlatılır. Bu yüzden yalnızca onu yakalayıp anlamlı bir şey yapmak, her hatayı genel bir catch ile karşılamaktan daha doğrudur.
Yanlış kullanım boş catch bloğudur:
try
{
File.ReadAllText("rapor.txt");
}
catch (IOException)
{
}
Bu kodda hata yutulur, dosya işlenmemiş kalır ve kullanıcı bundan haberdar olmaz. Doğru yaklaşım hatayı yakalayıp mesajını yazmak ya da loglamak, gerekirse kısa süre bekleyip birkaç kez yeniden denemek ve sonunda başarısızlığı bildirmektir. Aşağıdaki örnek kilidi kasıtlı olarak oluşturur: aynı programda dosya FileShare.None ile açık tutulur ve ikinci bir okuma denenir.
using System;
using System.IO;
using System.Threading;
class Program
{
static void Main()
{
string yol = "kilitli.txt";
File.WriteAllText(yol, "merhaba");
using (var kilit = new FileStream(yol, FileMode.Open, FileAccess.Read, FileShare.None))
{
const int denemeSayisi = 3;
for (int deneme = 1; deneme <= denemeSayisi; deneme++)
{
try
{
Console.WriteLine(File.ReadAllText(yol));
break;
}
catch (IOException ex)
{
Console.WriteLine($"Deneme {deneme}/{denemeSayisi} başarısız: {ex.Message}");
if (deneme == denemeSayisi)
Console.WriteLine("Dosya okunamadı, işlem yarım kaldı.");
else
Thread.Sleep(500);
}
}
}
}
}
Beklenen konsol çıktısı şuna benzer olur; hata metninin ayrıntısı işletim sistemine göre değişebilir:
Deneme 1/3 başarısız: The process cannot access the file '...kilitli.txt' because it is being used by another process.
Deneme 2/3 başarısız: The process cannot access the file '...kilitli.txt' because it is being used by another process.
Deneme 3/3 başarısız: The process cannot access the file '...kilitli.txt' because it is being used by another process.
Dosya okunamadı, işlem yarım kaldı.
Buradaki 3 deneme ve 500 milisaniyelik bekleme yalnızca örnek değerlerdir; sabit bir kural değildir. Örnekte kilit program yaşadığı sürece açık kaldığı için üç deneme de başarısız olur. Yeniden deneme kök nedeni çözmez. Yalnızca birkaç saniye içinde kendiliğinden kalkan geçici kilitlerde işe yarayabilir. Açık kalmış bir akış ya da başka bir uygulamanın tuttuğu kilit için önce nedeni gidermen gerekir.
Hatayla karşılaşınca izleyeceğin beş maddelik kontrol listesi
Hata mesajını gördüğünde kodu rastgele değiştirmek yerine şu sırayla ilerle:
- Hangi dosyaya erişildiğini bul. Hata mesajındaki dosya yolunu ve çağrı yığınındaki (stack trace) ilk satırı oku. Sorunlu dosyayı belirlemeden aramaya başlama.
- O dosyayı açan her yeri bul.
FileStream,StreamReaderveStreamWriternesnelerinin her birininusingile sarılı olup olmadığına bak. Kapanmayan tek bir akış bile sonraki erişimi engelleyebilir. - Aynı yola programda ikinci bir erişim olup olmadığını kontrol et. Bir akış hâlâ açıkken aynı dosyayı yeniden açmaya çalışan bir metot, döngü ya da olay işleyicisi var mı, kontrol et.
- Dışarıdaki nedenleri ele. Dosyayı başka bir uygulamanın açık tutuyor olabileceğini, programının önceki bir çalışmasının hâlâ arka planda sürüyor olabileceğini ya da hata ayıklayıcının eski oturumunun kapanmamış olabileceğini düşün. Bunları tek tek kapatıp hatanın değişip değişmediğini izle.
IOException'ı yakala, anlamlı bir mesajla bildir, hatayı yutma. Dosya yolunu ve işlemi içeren bir mesaj yaz; boş bircatchbloğu bırakma.
Dosya işlemleri ve temel C# kavramlarında hangi noktada olduğunu görmek istersen, yalnızca seviye ölçümü yapan ücretsiz C# bilgi testini çözebilirsin. Sonuç, hangi konuları tekrar edeceğini belirlemene yardımcı olabilir.
Sık Sorulan Sorular
File.ReadAllText ya da File.WriteAllText kullanırsam using yazmam gerekir mi?
Hayır. Bu metotlar dosyayı kendileri açar, işlemi yapar ve işlem bitince kapatır; senin ayrıca akış nesnesi yönetmen gerekmez. Yine de aynı anda başka bir akış ya da uygulama dosyayı tutuyorsa bu metotlar da aynı hatayı verebilir.
FileShare.ReadWrite kullanmak bu hatayı çözmek için güvenli bir yol mu?
Her durumda değil. Paylaşım ayarı yalnızca senin açışını değil, dosyayı zaten açmış olan tarafın ayarını da ilgilendirir; iki tarafın istekleri uyuşmazsa hata sürebilir. Birden fazla yazıcı aynı dosyaya aynı anda yazarsa içerik de bozulabilir. Önce akışların kapandığından emin ol, paylaşımı ancak gerçekten eşzamanlı erişim gerektiğinde bilinçli olarak aç.
Hatanın nedeni kendi programım mı yoksa başka bir uygulama mı, nasıl ayırt ederim?
Programını tamamen kapat, hata ayıklama oturumunu sonlandır ve dosyayı Dosya Gezgini'nde silmeyi ya da yeniden adlandırmayı dene. Dosya hâlâ kilitliyse başka bir uygulama tutuyor olabilir. Windows'ta Kaynak İzleyicisi'nin ilişkili tanıtıcılar bölümünde dosya adıyla arama yapmak da hangi işlemin dosyayı açık tuttuğunu göstermeye yardımcı olabilir. Program çalışırken hata oluyor ama kapattığında kayboluyorsa önce kendi kodundaki açık akışlara bak.
Bu hata Windows dışındaki işletim sistemlerinde de çıkar mı?
Kilitleme ve dosya paylaşımı işletim sistemine göre farklı davranabilir. Bu yüzden aynı kod bir sistemde hata verirken başka bir sistemde hiç hata vermeyebilir; mesaj metni de değişebilir. Taşınabilir bir program yazıyorsan akışları düzgün kapatmak ve IOException'ı yakalamak her sistemde güvenli bir alışkanlıktır.
Bu hata çoğu zaman bir akışın ne zaman açılıp ne zaman kapandığını izleyince çözülür. Kontrol listesini bir kez uyguladığında, sonraki karşılaşmalarında nedeni çok daha hızlı bulursun.