CodeGym /Kurslar /JAVA 25 SELF /IOException və FileNotFoundException: xətaların işlənməsi...

IOException və FileNotFoundException: xətaların işlənməsi

JAVA 25 SELF
Səviyyə , Dərs
Mövcuddur

1. Giriş-çıxış istisnalarının iyerarxiyası

Java-da fayllar və digər xarici resurslarla işləyərkən demək olar ki, həmişə giriş-çıxış istisnaları ilə rastlaşırıq. Bunlar, məlumatları oxuma və ya yazma zamanı nəsə qaydasında getmədikdə atılan (throw) obyektlərdir. Məsələn, fayl tapılmırsa, icazə yoxdursa və ya disk qəfil “yorulub”.

Mühazirəmizin əsas iştirakçıları

Java-da belə istisnaların bütöv bir iyerarxiyası var. Əsasları bunlardır:

  • IOException — giriş-çıxış xətalarının hamısı üçün əsas sinif. Fayllar, axınlar və ya şəbəkə ilə bağlı nəsə qaydasında deyilsə — demək olar ki, həmişə “günahkar” odur (və ya onun çoxsaylı törəmələrindən biri).
  • FileNotFoundExceptionIOException-un “oğlu”, mövcud olmayan faylı açmağa cəhd etdikdə və ya yol səhv göstərildikdə ortaya çıxır.

Digər törəmələr:

  • EOFException — o da IOException-un birbaşa “oğludur”. Oxuma zamanı gözlənilmədən faylın sonuna çatdığımızı siqnal verir.
  • MalformedInputException — “nəvə”: CharacterCodingException-dan miras alır, o isə öz növbəsində IOException-dan miras alır. Bu xəta faylı göstərilən kodlaşdırmada düzgün şərh etmək mümkün olmadıqda yaranır (məsələn, "UTF-8" gözlənilirdi, amma ardıcıllıq zədələnib).
  • Bir də SocketException, ZipException və digər ixtisaslaşmış “qohumlar” var — hərəsinin öz məsuliyyət sahəsi. İyerarxiyada nə qədər dərin olsa, vəziyyət bir o qədər dar və spesifik olur.

Kiçik, sadələşdirilmiş sxem:

java.lang.Exception
└── java.io.IOException
    ├── java.io.FileNotFoundException
    ├── java.io.EOFException
    ├── java.nio.charset.MalformedInputException
    └── ... (drugie)

Maraqlı fakt:
Java-da demək olar ki, bütün fayl əməliyyatları IOException-un elanını və ya işlənməsini tələb edir — bunlar checked istisnalardır. Kompilyator sizə səhvlərin işlənməsini unutmağa imkan verməyəcək!

2. Bu istisnalar nə zaman və niyə yaranır

Mövcud olmayan faylın açılması

Ən çox rast gəlinən hal — faylı açmağa çalışırsınız, amma o yoxdur. Bu, dayanacağa gəlib, hətta cədvəldə belə mövcud olmayan avtobusu gözləməyə bənzəyir.

FileInputStream fis = new FileInputStream("abracadabra.txt"); // Bum! FileNotFoundException

İcazəsiz fayla yazmağa cəhd

Əgər yazmaq üçün icazəniz olmayan qovluğa fayl yazmağa çalışsanız, vəziyyətdən asılı olaraq FileNotFoundException və ya IOException alacaqsınız.

FileOutputStream fos = new FileOutputStream("/system/secret.txt"); // Bum! FileNotFoundException və ya IOException

Daşıyıcı zədələndiyinə görə oxuma/yazma xətaları

Bəzən fayl guya var, amma disk zədələnib, fayl başqa proqram tərəfindən istifadə olunur və ya elektrik qəfil sönür — onda müxtəlif mesajlarla IOException alacaqsınız.

Digər səbəblər

  • Fayl yalnız oxuma üçün açılıb, siz isə yazmağa cəhd edirsiniz.
  • Faylın yolu çox uzundur və ya yolverilməz simvollar ehtiva edir.
  • Fayl başqa bir proses tərəfindən istifadə edilir.
  • Disk doludur.
  • Fayl, yoxlama ilə istifadə arasında, başqa proses tərəfindən silinib.

3. try-catch ilə işləmə

Fayllarla, axınlarla, şəbəkə ilə işlədiyiniz hər dəfə try-catch istifadə edin. Bu, təhlükəsizlik yastığı kimidir: nəsə qaydasında getməsə, proqram yıxılmayacaq, düzgün reaksiya verə biləcək.

İstisnaları düzgün necə tutmalı?

Java-da daha konkret istisnaları ümumilərdən əvvəl tutmaq lazımdır. Əgər ilk olaraq ümumi catch (IOException e) yazsanız, daha dar, məsələn FileNotFoundException, sadəcə işləməyəcək — ona nəzarət çatmayacaq.

Düzgün quruluş:

try {
    // Fayl ilə iş
} catch (FileNotFoundException e) {
    // "fayl tapılmadı" vəziyyətinin işlənməsi
} catch (IOException e) {
    // Digər giriş-çıxış xətalarının işlənməsi
}

Niyə belə?
Çünki FileNotFoundExceptionIOException-un xüsusi halıdır. Əgər ümumi halı əvvəlcə tutsanız, xüsusi hal öz catch-inə çatmayacaq.

Kod nümunəsi: fayl açılarkən xətaların işlənməsi

import java.io.*;

public class FileReaderExample {
    public static void main(String[] args) {
        String filename = "notes.txt";
        try {
            BufferedReader reader = new BufferedReader(new FileReader(filename));
            String line = reader.readLine();
            System.out.println("Faylın birinci sətri: " + line);
            reader.close();
        } catch (FileNotFoundException e) {
            System.out.println("Fayl tapılmadı: " + filename);
        } catch (IOException e) {
            System.out.println("Faylı oxuyarkən xəta: " + e.getMessage());
        }
    }
}

Diqqət yetirin:
Faylın mövcudluğunu yoxlamısınızsa belə, hər halda try-catch istifadə edin — fayl istənilən an yox ola bilər (məsələn, onu başqa proses silə bilər).

4. Təcrübə: xətaların işlənməsi ilə kod yazaq

Sadə nümunələr yaradacağıq və onların faylın olmamasına və digər xətalara düzgün reaksiya verməsini təmin edəcəyik.

Addım 1: Mövcud olmayan faylı açmağı sınayaq

import java.io.*;

public class NotesApp {
    public static void main(String[] args) {
        String filename = "my_notes.txt";
        try {
            BufferedReader reader = new BufferedReader(new FileReader(filename));
            String line;
            System.out.println("Qeydləriniz:");
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            reader.close();
        } catch (FileNotFoundException e) {
            System.out.println("Ay! Qeydlər faylı tapılmadı: " + filename);
            System.out.println("Məsləhət: faylı yaradın və ya adı yoxlayın.");
        } catch (IOException e) {
            System.out.println("Faylı oxuyarkən xəta baş verdi: " + e.getMessage());
        }
    }
}

Addım 2: Fayla yazma üçün işlənməni əlavə edək

import java.io.*;

public class NotesWriter {
    public static void main(String[] args) {
        String filename = "my_notes.txt";
        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter(filename, true)); // append: true
            writer.write("Yeni qeyd!\n");
            writer.close();
            System.out.println("Qeyd uğurla əlavə edildi!");
        } catch (IOException e) {
            System.out.println("Fayla yazarkən xəta: " + e.getMessage());
        }
    }
}

Addım 3: Səhvlərin jurnallaşdırılması ilə universal nümunə

import java.io.*;

public class SafeFileCopier {
    public static void main(String[] args) {
        String source = "source.txt";
        String target = "target.txt";
        try {
            BufferedReader reader = new BufferedReader(new FileReader(source));
            BufferedWriter writer = new BufferedWriter(new FileWriter(target));
            String line;
            while ((line = reader.readLine()) != null) {
                writer.write(line);
                writer.newLine();
            }
            reader.close();
            writer.close();
            System.out.println("Fayl uğurla köçürüldü!");
        } catch (FileNotFoundException e) {
            System.out.println("Fayl tapılmadı: " + e.getMessage());
        } catch (IOException e) {
            System.out.println("Giriş-çıxış xətası: " + e.getMessage());
        }
    }
}

Məsləhət:
Real tətbiqlərdə xətaları yalnız ekrana deyil, fayla və ya jurnala da yazın ki, sonradan nəyin səhv getdiyini anlamaq mümkün olsun.

5. Cədvəl: əsas IO istisnaları

İstisna Nə zaman yaranır? Necə işlənməlidir?
FileNotFoundException
Fayl tapılmır, yol mövcud deyil, icazə yoxdur İstifadəçiyə bildirin, yolu/icazələri yoxlayın, zərurət olduqda fayl yaradın
EOFException
Oxuma zamanı gözlənilməz fayl sonu Zədələnmə/naqislik barədə bildirin, mümkün olduqda məlumatları qismən bərpa etməyə çalışın
IOException
Ümumi giriş-çıxış xətası (disk, icazələr, kilidləmə) Detalları yoxlayın, əməliyyatı düzgün tamamlayın, mümkünsə yenidən cəhd edin
MalformedInputException
Yanlış kodlaşdırma və ya fayl strukturu Zədələnmə barədə məlumat verin, başqa kodlaşdırmanı/mənbəni sınayın

6. IO istisnalarının işlənməsində tipik səhvlər

Səhv № 1: Yalnız ümumi Exception-u tutmaq. Sadəcə catch (Exception e) yazmaq cazibədar görünür, lakin bu halda nəyin dəqiq səhv getdiyini ayırda bilməyəcəksiniz. Yaxşısı budur ki, əvvəlcə konkret istisnaları (FileNotFoundException), sonra isə ümumi IOException-u tutun.

Səhv № 2: Xəta baş verdikdə axınları bağlamamaq. Əgər faylı açmısınızsa və sonra istisna yaranıbsa, axın bağlı qalmaya bilər. try-with-resources-dan istifadə edin və ya resursları finally-də bağlayın.

Səhv № 3: İstisna mesajlarını nəzərə almamaq. Sadəcə “Xəta!” deməyin, detalları göstərin: e.getMessage(). Bu, nəyi daha tez anlamağa kömək edəcək.

Səhv № 4: Yazma zamanı FileNotFoundException-u işləməmək. Bir çoxları FileNotFoundException-un yalnız oxuma ilə bağlı olduğunu düşünür. Əslində o, yazma zamanı da yarana bilər (səhv yol, fayl yaratmağa icazənin olmaması və s.).

Səhv № 5: Giriş icazələrini yoxlamamaq. Proqram məhdud icazələrlə işə salınarsa, fayllarla bir çox əməliyyatlar xətayla başa çata bilər. Bunu həmişə nəzərə alın və istifadəçini məlumatlandırın.

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION