CodeGym /Kurslar /C# SELF /Fayl istisnalarını tutmaq (

Fayl istisnalarını tutmaq ( try-catch)

C# SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş

Fayl əməliyyatları demək olar ki, həmişə proqramdan kənar şəraitlə bağlı olur: fayl silinə bilər, daşına bilər, başqa bir proqram tərəfindən kilidlənə bilər, birdən istifadəçinin icazələri bitə bilər və ya diskdə boş yer qalmaya bilər. Bütün bunlar istisnalara səbəb ola bilər — proqramın icrasının dayandığı və istisna obyekti "atıldığı" xüsusi hallardır (Exception). Belə istisnaları tutub emal etməsəniz, proqramınız səhvlə bitəcək və istifadəçiyə konsolda qorxulu qırmızı mətn göstərəcək (və ya daha pis — səssizcə çökəcək).

C#-da bu cür hallar üçün try-catch bloku (sadə desək, "səhv tələsi") istifadə olunur. Bu, yalnız səhvi "tutmağa" imkan vermir, həm də növbəti addımı sakitcə müəyyən etməyə icazə verir: dostyana mesaj göstərmək, başqa fayl seçməyi təklif etmək, xətanı log-a yazmaq və ya sadəcə yenidən cəhd etmək.

Real tətbiqlərdə

Əgər siz konsol kalkulyatoru yazırsınızsa, fayllarla işləyərkən səhvləri tutmadan da keçinmək olar. Amma əgər sənəd emal edən müəssisə proqramı və ya oyun yazırsınızsa ki, orada proses yadda saxlanılır — belə səhvləri emal etməmək təhlükəsiz kordon olmadan ipdə gəzmək kimidir: gec-tez nəsə baş verəcək.

2. İstisnalarla işə qayıdaq

Əsas sintaksis of try-catch

Fayllarla bağlı konkret hallara keçməzdən əvvəl, try-catch konstruktsiyasının əsas sintaksisini xatırlayaq (bu, istisnələr haqqında mühazirələrdə artıq görmüşdüyümüzdür):


try
{
    // Burada "atmaq" (throw) mümkün olan kod
}
catch (Exception ex)
{
    // Burada biz bütün mümkün istisnaları tuturuq... Amma belə etmək yaxşı deyil!
    Console.WriteLine("Nəsə səhv getdi: " + ex.Message);
}

try daxilində potensial təhlükəli kodu yazırıq, catch-də isə nə etməli olduğumuzu müəyyən edirik.

Proqramçı zarafatı: "try-catch — bu səhvlər üçün rəqəmsal görünməzlik papağı kimidir. Səhv var, amma onu görmürsən!"

Fayl istisnaları

.NET vasitəsilə fayllarla işləyərkən, adətən istisnalarla rastlaşırsınız — məsələn, stream yaratarkən, oxuyub yazarkən. Bir neçə tipik ssenari və əlaqəli istisnalar:

  • Fayl tapılmadı → FileNotFoundException
  • Fayla/kataloga giriş yoxdur → UnauthorizedAccessException
  • Yol ilə bağlı problemlər (məsələn, yaramaz simvollar, çox uzun yol) → PathTooLongException, ArgumentException
  • Fayl başqa proses tərəfindən istifadə olunur → IOException
  • Diskdə boş yer yoxdur → IOException

Çox vaxt fayl əməliyyatları birbaşa IOException-dan törənən istisnalarla bağlı olur. Onların hamısı bazadan System.Exception miras alır.

3. Praktika: fayllarla işləyərkən səhvləri tutmaq və emal etmək

Gəlin nümunə ssenarilərə baxaq: təsəvvür edək ki, salamlaşma mətnini fayldan oxumağa, emal etməyə və istifadəçiyə göstərməyə çalışırıq. Burada try-catch ilə səhv yoxlamasını əlavə edəcəyik.

Nümunə 1: "fayl tapılmadı" emalı


string filePath = "hello.txt";

try
{
    string greeting = File.ReadAllText(filePath);
    Console.WriteLine("Faylın məzmunu: " + greeting);
}
catch (FileNotFoundException ex)
{
    Console.WriteLine("Fayl tapılmadı! Yoxlayın ki, fayl " + filePath + " mövcuddur.");
    // Əlavə olaraq texniki detalları da göstərə bilərik
    Console.WriteLine("Texniki detal: " + ex.Message);
}

Əgər "hello.txt" faylı yoxdursa, proqram səhvlə bitməyəcək, əksinə dostyana mesaj verəcək. Bu qədər sadəliklə proqramı istifadəçinin "səhvlərinə" davamlı edirik.

Nümunə 2: İcazə pozuntusu

Daha çətin hal götürək: fayl var, amma onu oxumaq üçün icazəmiz yoxdur (məsələn, kiminsə yalnız yazma icazəsi var və ya fayl qorunan qovluqdadır).


try
{
    string secret = File.ReadAllText("C:\\Windows\\System32\\config.txt");
}
catch (UnauthorizedAccessException ex)
{
    Console.WriteLine("Fayla giriş yoxdur! Proqramı administrator kimi işə salmağı yoxlayın.");
    Console.WriteLine("Texniki səbəb: " + ex.Message);
}

Nümunə 3: Ümumi IOException

Bəzi səhvlər faylın başqa proses tərəfindən kilidlənməsi, diskin dolu olması və ya avadanlıq problemləri ilə bağlı ola bilər:


try
{
    File.WriteAllText("important.txt", "Vacib məlumat!");
}
catch (IOException ex)
{
    Console.WriteLine("Faylla işləyərkən səhv: çox güman başqa proqram faylı istifadə edir və ya diskdə yer yoxdur.");
    Console.WriteLine("Texniki səbəb: " + ex.Message);
}

4. Bir neçə istisnanı tutmaq: seçmə emal

Bəzən müxtəlif istisna növlərinə fərqli reaksiya vermək lazımdır. .NET bir neçə catch blokunu eyni anda yazmağa imkan verir — daha spesifikdən ümuma doğru (əks halda kompilyator kəskin etiraz edəcək).


try
{
    string content = File.ReadAllText("file.txt");
    Console.WriteLine(content);
}
catch (FileNotFoundException ex)
{
    Console.WriteLine("Fayl tapılmadı.");
}
catch (UnauthorizedAccessException ex)
{
    Console.WriteLine("Fayla giriş yoxdur!");
}
catch (IOException ex)
{
    Console.WriteLine("Başqa I/O xətası: " + ex.Message);
}

Vacib: əgər catch (Exception ex) blokunu ilk qoysanız, digər blokların mənası olmayacaq, çünki əsas tip hər şeyi tutacaq!

5. Daxili try-catch və təkrar cəhdlər

Bəzən siz yalnız xətanı emal etmək deyil, həm də istifadəçiyə "düzəltmək" şansı vermək istəyirsiniz — məsələn, mövcud fayl yolunu daxil etməyi təklif etmək:


string filePath;
string content;
int attempts = 0;
const int maxAttempts = 3;

do
{
    Console.Write("Faylın yolunu daxil edin: ");
    filePath = Console.ReadLine();

    try
    {
        content = File.ReadAllText(filePath);
        Console.WriteLine("Faylın məzmunu:\n" + content);
        break;
    }
    catch (FileNotFoundException)
    {
        Console.WriteLine("Fayl tapılmadı! Yenidən cəhd edin.");
    }
    catch (UnauthorizedAccessException)
    {
        Console.WriteLine("Fayla giriş yoxdur! Başqa fayl seçin.");
    }
    attempts++;
}
while (attempts < maxAttempts);

if (attempts == maxAttempts)
    Console.WriteLine("Çox sayda uğursuz cəhd oldu.");

Bu kod istifadəçini düzgün fayl yolunu xatırlamasına kömək edən kiçik "dostluq interfeysi" kimidir.

6. Tipik səhvlər və xüsusiyyətlər: laqeydlikdən şüurlu yanaşmaya

Yeni başlayanların (və hətta təcrübəli inkişaf etdiricilərin) çox rastlaşdığı səhv — bütün istisnaları ard-arda tutmaq, sadəcə catch (Exception) yazmaq və "Səhv baş verdi!" mesajı göstərməkdir. Bu yanaşma bir neçə səbəbdən pisdir. Birincisi, bu, biznes-logic-də real boşluqları gizlədir. İkincisi, faylla bağlı olmayan xətalar (məsələn, kodda tip səhvi və ya riyazi səhv) təsadüfən udula bilər və həqiqi səbəbin tapılması uzun çəkə bilər.

Daha yaxşısı — yalnız məntiqli şəkildə emal edə biləcəyiniz xətaları açıq şəkildə tutmaqdır. Hansı xəta baş verdiyi aydın deyilsə, onu tutmamaq daha məqsədəuyğundur: beləliklə tətbiq "uçacaq" və siz çağırış zəncirini (stack trace) görüb problemi düzəldə biləcəksiniz.

Xüsusiyyət: Bəzi istisnaların içində əlavə səbəblər olur (InnerException). Onları log-larda analiz etmək rahatdır, xüsusən xətaları diaqnoz edərkən.

Başqa bir nüans — əgər catch-dən sonra proqramın işləməsi mümkün deyilsə (məsələn, əsas konfiq faylını açmaq alınmayıb), icranı return ilə bitirmək və ya xətanı yenidən atmaq (throw;) məntiqlidir — beləliklə "yarımçıq" funksiyaları olan "zombi-proqramlar" əmələ gəlməz.

2
Tapşırıq
C# SELF, səviyyə, dərs
Bağlanıb
Fayla yazarkən bir neçə istisnanın işlənməsi
Fayla yazarkən bir neçə istisnanın işlənməsi
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION