CodeGym /Kurse /JAVA 25 SELF /IOException und FileNotFoundException: Fehlerbehandlung

IOException und FileNotFoundException: Fehlerbehandlung

JAVA 25 SELF
Level 38, Lektion 0
Verfügbar

1. Hierarchie der I/O-Exceptions

In Java muss man bei der Arbeit mit Dateien und anderen externen Ressourcen fast immer mit sogenannten Ein-/Ausnahmefehlern (I/O-Exceptions) rechnen. Das sind Objekte, die geworfen werden (throw), wenn beim Lesen oder Schreiben von Daten etwas schiefgeht. Zum Beispiel, wenn die Datei nicht gefunden wird, der Zugriff verweigert ist oder die Festplatte plötzlich „schlappmacht“.

Die Hauptakteure unserer Vorlesung

In Java gibt es eine ganze Hierarchie solcher Exceptions. Hier sind die wichtigsten:

  • IOException — Basisklasse für alle I/O-Fehler. Wenn mit Dateien, Streams oder dem Netzwerk etwas nicht klappt — fast immer ist sie (oder eine ihrer zahlreichen Unterklassen) im Spiel.
  • FileNotFoundException — Unterklasse von IOException, die auftritt, wenn Sie versuchen, eine nicht existierende Datei zu öffnen oder der Pfad falsch ist.

Weitere abgeleitete Typen:

  • EOFException — ebenfalls eine direkte Unterklasse von IOException. Signalisiert, dass wir beim Lesen unerwartet ans Datei-Ende gekommen sind.
  • MalformedInputException — „Enkel“: erbt von CharacterCodingException, die wiederum von IOException erbt. Dieser Fehler tritt auf, wenn eine Datei in der angegebenen Kodierung nicht korrekt interpretiert werden kann (z. B. wurde "UTF-8" erwartet, es kommt aber eine defekte Sequenz).
  • Außerdem gibt es SocketException, ZipException und andere spezialisierte „Verwandte“, jeweils mit ihrem eigenen Zuständigkeitsbereich. Je tiefer in der Hierarchie, desto spezieller die Situation.

Kleine vereinfachte Übersicht:

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

Interessante Tatsache:
In Java müssen nahezu alle Dateioperationen IOException deklarieren oder behandeln — das sind sogenannte Checked Exceptions. Der Compiler lässt Sie die Fehlerbehandlung nicht vergessen!

2. Wann und warum diese Exceptions auftreten

Öffnen einer nicht vorhandenen Datei

Der häufigste Fall — Sie versuchen, eine Datei zu öffnen, die es nicht gibt. Das ist wie an eine Haltestelle zu kommen, an der es den Bus nicht einmal im Fahrplan gibt.

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

Versuch, in eine Datei ohne Rechte zu schreiben

Wenn Sie versuchen, in einen Ordner zu schreiben, für den Sie keine Rechte haben, erhalten Sie FileNotFoundException oder IOException (je nach Situation).

FileOutputStream fos = new FileOutputStream("/system/secret.txt"); // Peng! FileNotFoundException oder IOException

Lesen/Schreiben schlägt wegen beschädigtem Datenträger fehl

Manchmal ist die Datei zwar vorhanden, aber der Datenträger ist beschädigt, die Datei ist von einem anderen Programm belegt oder der Strom fällt plötzlich aus — dann erhalten Sie eine IOException mit unterschiedlichen Meldungen.

Weitere Gründe

  • Datei ist schreibgeschützt, Sie versuchen aber zu schreiben.
  • Der Pfad ist zu lang oder enthält unzulässige Zeichen.
  • Die Datei wird von einem anderen Prozess verwendet.
  • Der Datenträger ist voll.
  • Die Datei wurde von einem anderen Prozess zwischen Prüfung und Verwendung gelöscht.

3. Behandlung mit try-catch

Immer wenn Sie mit Dateien, Streams oder dem Netzwerk arbeiten — verwenden Sie try-catch. Das ist wie ein Airbag: Wenn etwas schiefgeht, stürzt das Programm nicht ab, sondern kann angemessen reagieren.

Wie fängt man Exceptions richtig?

In Java fängt man spezifischere Exceptions früher als allgemeinere. Wenn Sie den allgemeinen catch (IOException e) zuerst platzieren, werden speziellere wie FileNotFoundException nicht mehr erreicht — die Ausführung gelangt nicht bis zu ihnen.

Richtige Struktur:

try {
    // Arbeit mit der Datei
} catch (FileNotFoundException e) {
    // Behandlung der Situation "Datei nicht gefunden"
} catch (IOException e) {
    // Behandlung anderer I/O-Fehler
}

Warum ist das so?
Weil FileNotFoundException ein Sonderfall von IOException ist. Wenn Sie den allgemeinen Fall früher fangen, erreicht der spezielle seinen catch nicht.

Codebeispiel: Fehlerbehandlung beim Öffnen einer Datei

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("Erste Zeile der Datei: " + line);
            reader.close();
        } catch (FileNotFoundException e) {
            System.out.println("Datei nicht gefunden: " + filename);
        } catch (IOException e) {
            System.out.println("Fehler beim Lesen der Datei: " + e.getMessage());
        }
    }
}

Beachten Sie:
Selbst wenn Sie geprüft haben, dass die Datei existiert, sollten Sie immer try-catch verwenden — die Datei kann jederzeit verschwinden (z. B. wird sie von einem anderen Prozess gelöscht).

4. Praxis: wir schreiben Code mit Fehlerbehandlung

Wir erstellen einfache Beispiele und sorgen dafür, dass sie korrekt auf fehlende Dateien und andere Fehler reagieren.

Schritt 1: Versuch, eine nicht vorhandene Datei zu öffnen

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("Ihre Notizen:");
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            reader.close();
        } catch (FileNotFoundException e) {
            System.out.println("Ups! Notizdatei wurde nicht gefunden: " + filename);
            System.out.println("Tipp: Erstellen Sie die Datei oder prüfen Sie den Namen.");
        } catch (IOException e) {
            System.out.println("Beim Lesen der Datei ist ein Fehler aufgetreten: " + e.getMessage());
        }
    }
}

Schritt 2: Wir fügen die Behandlung für das Schreiben in eine Datei hinzu

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("Neue Notiz!\n");
            writer.close();
            System.out.println("Notiz erfolgreich hinzugefügt!");
        } catch (IOException e) {
            System.out.println("Fehler beim Schreiben in die Datei: " + e.getMessage());
        }
    }
}

Schritt 3: Universelles Beispiel mit Fehler-Logging

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("Datei erfolgreich kopiert!");
        } catch (FileNotFoundException e) {
            System.out.println("Datei nicht gefunden: " + e.getMessage());
        } catch (IOException e) {
            System.out.println("I/O-Fehler: " + e.getMessage());
        }
    }
}

Tipp:
In realen Anwendungen sollten Sie Fehler nicht nur auf dem Bildschirm ausgeben, sondern auch in eine Datei oder ein Log schreiben, um später nachvollziehen zu können, was genau schiefgelaufen ist.

5. Tabelle: wichtigste I/O-Exceptions

Exception Wann tritt sie auf? Wie behandeln?
FileNotFoundException
Datei nicht gefunden, Pfad existiert nicht, keine Rechte Nutzer informieren, Pfad/Rechte prüfen, Datei bei Bedarf anlegen
EOFException
Unerwartetes Datei-Ende beim Lesen Über Beschädigung/Unvollständigkeit informieren, Daten ggf. teilweise wiederherstellen
IOException
Allgemeiner I/O-Fehler (Datenträger, Berechtigungen, Sperre) Details prüfen, Operation sauber beenden, nach Möglichkeit erneut versuchen
MalformedInputException
Ungültige Zeichenkodierung oder Dateistruktur Über Beschädigung informieren, andere Kodierung/Quelle versuchen

6. Typische Fehler bei der Behandlung von I/O-Exceptions

Fehler Nr. 1: Nur den allgemeinen Exception fangen. Es ist verlockend, einfach catch (Exception e) zu schreiben, aber dann können Sie nicht unterscheiden, was genau schiefgelaufen ist. Fangen Sie besser zuerst konkrete Exceptions (FileNotFoundException) und danach die allgemeine IOException.

Fehler Nr. 2: Streams bei Fehlern nicht schließen. Wenn Sie eine Datei geöffnet haben und dann eine Exception auftritt, kann der Stream ungeschlossen bleiben. Verwenden Sie try-with-resources oder schließen Sie Ressourcen in finally.

Fehler Nr. 3: Exception-Meldungen ignorieren. Geben Sie nicht einfach „Fehler!“ aus, sondern zeigen Sie Details: e.getMessage(). Das hilft, schneller zu verstehen, was schiefgelaufen ist.

Fehler Nr. 4: FileNotFoundException beim Schreiben nicht behandeln. Viele denken, FileNotFoundException betreffe nur das Lesen. Tatsächlich kann sie auch beim Schreiben auftreten (ungültiger Pfad, keine Rechte zum Erstellen der Datei usw.).

Fehler Nr. 5: Zugriffsrechte nicht prüfen. Wenn das Programm mit eingeschränkten Rechten läuft, können viele Dateioperationen fehlschlagen. Berücksichtigen Sie das stets und informieren Sie den Nutzer.

1
Aufgabe
JAVA 25 SELF, Level 38, Lektion 0
Gesperrt
Suche nach einem verlorenen Eintrag in der alten Bibliothek 📚
Suche nach einem verlorenen Eintrag in der alten Bibliothek 📚
1
Aufgabe
JAVA 25 SELF, Level 38, Lektion 0
Gesperrt
Aufzeichnung einer wichtigen Botschaft im königlichen Archiv 📜
Aufzeichnung einer wichtigen Botschaft im königlichen Archiv 📜
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION