İçeriğe geç

Menü

Berk Akademi
Yorumlar Google yorumları Birebir ders başvurusu Ücretsiz ön görüşme Ana Sayfa

C# "System.IO.FileNotFoundException" Hatası Nasıl Çözülür?

csharp-system-io-filenotfoundexception-hatasi-cozumu
Bu yazıda neler var?
  1. Hata mesajı sana neyi söylüyor ve nereden başlamalısın?
  2. Göreli ve mutlak yol farkı: dosya neden 'yanında durduğu halde' bulunamıyor?
  3. Körlemesine File.Exists yerine: önce tam yolu yazdır, sonra doğrula
  4. Visual Studio'da dosya neden çıktı klasörüne gelmiyor?
  5. Dosya adı tuzakları: büyük küçük harf, uzantı ve gizli uzantı
  6. Sınır durumu: dosya değil, derleme bulunamadığında da aynı istisna çıkar
  7. Sık Sorulan Sorular

C#'ta System.IO.FileNotFoundException hatası, kodda verdiğin dosya yolunun programın çalıştığı yerde bir dosyaya karşılık gelmediği anlamına gelir. Çözmek için üç şeye bakarsın: istisna mesajındaki gerçek yola, göreli yolun hangi çalışma klasörüne göre hesaplandığına ve dosyanın derlenmiş çıktı klasörüne kopyalanıp kopyalanmadığına. Dosya projenin içinde, kod dosyanın hemen yanında durabilir; program yine de başka bir klasörde arıyor olabilir.

Hata mesajı sana neyi söylüyor ve nereden başlamalısın?

Mesaj genellikle Could not find file ifadesiyle başlar ve tek tırnak içinde bir yol gösterir. Mesajın dili .NET'in ve işletim sisteminin dil ayarına göre değişebilir; Türkçe bir ortamda karşına Türkçe bir ifade çıkabilir. Yol kısmı ise değişmez ve en değerli ipucudur.

Kodda "notlar.txt" gibi kısa bir ad yazmış olsan bile mesajda çoğu zaman tam yol görürsün. Bu yol, .NET'in dosyayı gerçekte aradığı yerdir. Aradığın klasör ile mesajdaki klasör aynı değilse sorunun kaynağını bulmuşsundur. İstisna nesnesinin FileName özelliği de bulunamayan dosyanın adını taşır; catch bloğunda bunu yazdırarak hangi dosyanın sorun çıkardığını görebilirsin.

Hızlı teşhis için şu sırayı izle:

  1. Mesajdaki yolu oku. Dosya adını ve klasörü, kodda yazdığınla karşılaştır. Ayrıntısı bu bölümde.
  2. Yolun göreli mi mutlak mı olduğuna bak. Sürücü ya da kökten başlamayan yol göreli yoldur. Ayrıntısı hemen sonraki bölümde.
  3. Çalışma dizinini yazdır. Göreli yolun hangi klasöre göre hesaplandığını tahmin etme, programa söylet. Ayrıntısı "Körlemesine File.Exists yerine" bölümünde.
  4. Dosyanın çıktı klasöründe olup olmadığına bak. Dosya projede görünse de derlenmiş çıktıya kopyalanmamış olabilir. Ayrıntısı Visual Studio bölümünde.
  5. Dosya adını, büyük küçük harfi ve uzantıyı kontrol et. Gizli uzantılar yüzünden notlar.txt aslında notlar.txt.txt olabilir. Ayrıntısı "Dosya adı tuzakları" bölümünde.

Göreli ve mutlak yol farkı: dosya neden 'yanında durduğu halde' bulunamıyor?

Göreli ve mutlak yol farkı: dosya neden 'yanında durduğu halde' bulunamıyor?

Mutlak yol, sürücü harfinden ya da kök dizinden başlar ve dosyayı tek başına tarif eder. Göreli yol ise yalnızca notlar.txt ya da veri/notlar.txt gibi bir ifadedir; hangi klasörden başlayacağı yolun kendisinde yazmaz. Burada kritik bilgi şudur:

Göreli dosya yolu, kod dosyasına göre değil uygulamanın çalışma dizinine göre değerlendirilir.

Yani .cs dosyasının durduğu klasör hesaba katılmaz. Kod dosyasının yanına bir metin dosyası koymak, programın onu bulacağı anlamına gelmez. Program zaten kaynak koddan değil, derlenmiş çıktıdan çalışır.

İki farklı klasör: çalışma dizini ve uygulamanın klasörü

Directory.GetCurrentDirectory() sürecin çalışma dizinini verir. Göreli yollar bu klasöre göre çözülür. Programı hangi araçtan ve hangi klasörden başlattığına göre bu değer değişebilir; bu yüzden tahmin yürütmek yerine kendin yazdırıp görmen en güvenlisidir.

AppContext.BaseDirectory ise uygulamanın çalıştığı derlenmiş çıktının bulunduğu klasörü verir. Dosyayı projeyle birlikte dağıtıp çıktı klasöründen okumak istiyorsan yolu bu klasörden başlatman daha tutarlı olur. Çalışma dizini başka bir yere kayarsa bu yol etkilenmez.

Yolu elle birleştirme, Path.Combine kullan

Klasör ile dosya adını + ve ters bölüyle birleştirmek, ayırıcıyı unutmaya ya da iki kez yazmaya açık bir yöntemdir. Ayırıcı karakter işletim sistemine göre de değişir. Path.Combine parçaları sistemin kullandığı ayırıcıyla birleştirir. Tek dikkat edeceğin nokta şu: sonraki parçalardan biri kökten başlayan bir yolsa, öncekiler yok sayılır. Bu yüzden ikinci parçaya "/notlar.txt" gibi bir ifade yazma.

Mantık şöyle kurulur: Path.Combine(AppContext.BaseDirectory, "notlar.txt") uygulamanın klasörünü başlangıç alır ve dosya adını güvenli biçimde ekler. Bu yolu çalışırken görüp File.Exists ile doğrulamak ise bir sonraki bölümün konusu.

Körlemesine File.Exists yerine: önce tam yolu yazdır, sonra doğrula

Dosyanın neden bulunamadığını tahmin etmek yerine programın aradığı yolu ekrana yazdır. Aşağıdaki örnek iki aday tam yol kurar: birincisi çalışma klasörüne, ikincisi uygulamanın çalıştığı çıktı klasörüne göre hesaplanır. Sonra her yol için File.Exists sonucunu gösterir.

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string dosyaAdi = "notlar.txt";
        string[] adaylar =
        {
            Path.Combine(Directory.GetCurrentDirectory(), dosyaAdi),
            Path.Combine(AppContext.BaseDirectory, dosyaAdi)
        };

        foreach (string yol in adaylar)
        {
            Console.WriteLine("Aday yol: " + yol);
            bool varMi = File.Exists(yol);
            Console.WriteLine("File.Exists: " + varMi);
            if (varMi)
            {
                Console.WriteLine(File.ReadAllText(yol));
            }
        }

        try
        {
            File.ReadAllText(adaylar[0]);
        }
        catch (FileNotFoundException e)
        {
            Console.WriteLine("Aranan dosya: " + e.FileName);
        }
    }
}

Dosya çıktı klasörüne kopyalanmamışsa çıktı şuna benzer:

Aday yol: <proje-klasoru>/bin/<yapilandirma>/<hedef-cati>/notlar.txt
File.Exists: False
Aday yol: <proje-klasoru>/bin/<yapilandirma>/<hedef-cati>/notlar.txt
File.Exists: False
Aranan dosya: <proje-klasoru>/bin/<yapilandirma>/<hedef-cati>/notlar.txt

Dosya o klasöre kopyalandığında iki satırda da File.Exists: True görürsün ve dosyanın içeriği yazdırılır. Programı farklı bir çalışma klasöründen başlatırsan birinci yol değişebilir; ikisini birlikte yazdırmanın amacı bu farkı görmendir.

File.Exists yol geçersizse ya da erişim izni yoksa da istisna fırlatmadan false döndürür. Bu yüzden False sonucu "dosya yok" demek değil, "bu yolda erişilebilir bir dosya bulunamadı" demektir. Yazdırdığın yolu Dosya Gezgini'nde açarak kontrol et.

catch bloğu sorunu çözmez, yalnızca bilgi toplar. e.FileName aranan dosyanın adını ya da yolunu verir; hatayı susturmak için kullanma. Dosya işlemleri ve istisnalar konusunda seviyeni görmek istersen ücretsiz C# bilgi testini çözebilirsin.

Visual Studio'da dosya neden çıktı klasörüne gelmiyor?

Visual Studio'da dosya neden çıktı klasörüne gelmiyor?

Çıktı klasörü, derlenen uygulamanın konduğu bin altındaki <yapilandirma>/<hedef-cati> klasörüdür; örneğin bin/Debug/<hedef-cati>. Program buradan çalışır. Proje klasörüne eklediğin bir metin dosyası ise kendiliğinden bu klasöre kopyalanmaz, bu yüzden kodun aradığı yerde bulunmaz.

Çözüm için şu adımları izle:

  1. Solution Explorer'da dosyaya tıkla.
  2. Properties penceresinde Copy to Output Directory ayarını bul.
  3. Değeri Copy always ya da Copy if newer olarak değiştir.
  4. Projeyi yeniden derle ve dosyanın çıktı klasöründe göründüğünü Dosya Gezgini'nden doğrula.

Seçeneklerin anlamı şöyledir: Do not copy dosyayı kopyalamaz, Copy always her derlemede kopyalar, Copy if newer yalnızca kaynak dosya daha yeniyse kopyalar. Aynı ayar .csproj dosyasında şöyle görünür:

<ItemGroup>
  <None Update="notlar.txt">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </None>
</ItemGroup>

Burada PreserveNewest "Copy if newer" seçeneğine, Always "Copy always" seçeneğine karşılık gelir. Kopyalama yapılmasını istemiyorsan öğeyi hiç eklemeyebilir ya da değeri Never yapabilirsin.

Kopyalamanın çalıştığını Dosya Gezgini'nde bin altındaki klasörü açıp dosyayı görerek kontrol et. Önceki bölümdeki örneği tekrar çalıştırdığında File.Exists sonucu True oluyorsa sorun çözülmüştür.

Dosya adı tuzakları: büyük küçük harf, uzantı ve gizli uzantı

Yol doğru klasörü gösteriyor olsa bile ad birebir tutmuyorsa dosya bulunamaz. Kodda yazdığın ad ile diskteki ad harfi harfine aynı olmalıdır. veri.txt yerine veriler.txt, ogrenci.txt yerine öğrenci.txt yazmak, addaki bir boşluğu atlamak ya da uzantıyı hiç yazmamak aynı istisnayı üretir.

Büyük küçük harf konusunda dosya sistemi belirleyicidir. Bazı sistemlerde Veri.txt ile veri.txt aynı dosya sayılır, bazılarında iki ayrı dosyadır. Kodu başka bir bilgisayara ya da işletim sistemine taşıdığında sürpriz yaşamamak için kodda ve diskte aynı yazımı kullan. Türkçe karakterlerde de aynı disiplin geçerlidir: ı ile i farklı harflerdir.

Gizli uzantı tuzağı

Windows'ta bilinen dosya uzantıları gizliyse Dosya Gezgini'nde metin.txt görünen bir dosyanın gerçek adı metin.txt.txt olabilir. Not Defteri'nde "Farklı kaydet" ile adı metin.txt yazıp kaydettiğinde bu sık yaşanır. Dosya Gezgini'nin görünüm ayarlarından dosya adı uzantılarını görünür yap; böylece gerçek adı olduğu gibi görürsün.

Gözle kontrol etmek yerine kodun gördüğü adı da yazdırabilirsin:

string klasor = AppContext.BaseDirectory;

foreach (string yol in Directory.GetFiles(klasor, "*.txt"))
{
    Console.WriteLine(Path.GetFileName(yol));
}

Dosya gizli uzantı yüzünden yanlış adlandırılmışsa çıktı şöyle olur:

metin.txt.txt

Kodda metin.txt aradığın için bulunamaz. Dosyayı yeniden adlandır ya da kodu gerçek adla eşleştir.

Kısa kontrol listesi: adı kopyalayıp koda yapıştır, uzantıyı yaz, boşluk ve Türkçe karakterleri gözden geçir, uzantıları görünür yap ve çıktı klasöründeki adı yukarıdaki gibi koddan listeleyip karşılaştır.

Sınır durumu: dosya değil, derleme bulunamadığında da aynı istisna çıkar

FileNotFoundException yalnızca metin ya da veri dosyaları için fırlatılmaz; uygulamanın ihtiyaç duyduğu bir derleme (DLL) yüklenemediğinde de çıkabilir. Bu durumda mesaj, Could not load file or assembly gibi başlayarak bir derleme adından söz eder. Sorun artık veri dosyasının yolunda değil, eksik ya da çıktıya kopyalanmamış bir bağımlılıktadır. Önce mesajdaki derleme adını oku. Sonra NuGet paketlerinin geri yüklendiğinden (restore) ve projeye ilgili başvurunun eklendiğinden emin ol. Son olarak çıktı klasöründe o DLL'in bulunup bulunmadığına bak.

Sık Sorulan Sorular

Dosyayı proje klasörüne koydum, neden hâlâ bulunamıyor?

Uygulama çalışırken göreli yolu proje klasörüne göre değil, kendi çalışma klasörüne göre çözer; bu klasör genellikle derlenmiş çıktının bulunduğu yerdir. Dosyanın çıktı klasörüne kopyalanması için Visual Studio'da dosyanın özelliklerindeki Copy to Output Directory ayarına bakmalısın. Emin olmak için tam yolu yazdırıp File.Exists ile doğrula.

try-catch ile FileNotFoundException'ı yakalamak sorunu çözer mi?

Hayır, yalnızca programın çökmesini engeller ve kullanıcıya anlaşılır bir mesaj göstermeni sağlar. Dosya yine yerinde değildir. Önce nedeni bul: yol, ad ya da çıktıya kopyalanma. Sonra File.Exists ile önceden kontrol et. try-catch'i, beklenmedik durumlar için ikinci güvence olarak tut.

Kod bende çalışıyor ama arkadaşımın bilgisayarında FileNotFoundException veriyor, neden?

En sık nedenler şunlardır: kodda kendi bilgisayarına özgü sabit bir mutlak yolun yazılı olması, dosyanın çıktı klasörüne kopyalanmaması ve dosya adındaki harf ya da uzantı farkı. Dosyayı projeyle birlikte taşıyıp AppContext.BaseDirectory ve Path.Combine ile yol kurmak bu farkları azaltır. Hata bir derleme adından söz ediyorsa paketlerin o bilgisayarda geri yüklendiğini de kontrol et.

Bu hatayı çözerken sırayı izlemen yeterli: hangi dosya adı, hangi çalışma klasörü, dosya çıktıda var mı. Bu üç soruyu tam yol çıktısıyla yanıtladığında sorun genellikle kendini gösterir.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara