/
/
·
·
/
/
·
·
  • Einführung
  • Die Idee in einem Satz
  • Byte-Streams vs. Char-Streams
  • Das Lese-Muster und das EOF-Signal
  • Buffering: warum BufferedReader
  • Moderne I/O: NIO (Files / Path)
  • Klausur-Faustregeln
  • Häufige Stolpersteine
ThemenProgrammiergrundlagenI/O und Datei-Handling
Programmiergrundlagen·4Lerneinheiten·26min·Stand18.07.2026

I/O und Datei-Handling.

Sobald dein Programm mit der Außenwelt redet, eine Datei liest, eine schreibt, übers Netzwerk kommuniziert, läuft das über Streams: einen Fluss von Daten, der Stück für Stück gelesen oder geschrieben wird. Java trennt dabei sauber zwischen Byte-Strömen (für Binärdaten) und Zeichen-Strömen (für Text). Wer das verwechselt, bekommt kaputte Umlaute oder unnötig komplizierten Code.

Was du können musst:

  • Byte-Streams (InputStream/OutputStream) von Char-Streams (Reader/Writer) unterscheiden
  • das Lese-Muster mit dem EOF-Signal kennen (read() liefert -1, readLine() liefert null)
  • Buffering verstehen (warum BufferedReader schneller ist)
  • Dateien sicher schließen (try-with-resources) und das richtige Encoding (UTF-8) wählen

Abgrenzung: hier die Grundlagen der Datei-I/O. Tiefes NIO (Channels, Buffers, Memory-Mapped Files, asynchrones I/O) ist Vertiefung.

Ein Stream ist ein Datenfluss: InputStream/Reader liest Daten herein, OutputStream/Writer schreibt hinaus, Stück für Stück, bis das Ende (EOF) erreicht ist.

Byte-StreamsChar-Streams
BasisklassenInputStream, OutputStreamReader, Writer
EinheitByte (0-255)Zeichen (mit Encoding)
WofürBinärdaten: Bilder, Audio, serialisierte ObjekteText: .txt, .csv, .json
EOF-Signalread() liefert -1readLine() liefert null

Faustregel: Text → Char-Stream (Reader/Writer), alles andere → Byte-Stream. Ein Char-Stream wandelt Bytes über ein Encoding (Charset, meist UTF-8) in Zeichen um; ein Byte-Stream tut das nicht.

// Byte-Stream: Datei roh als Bytes lesen
try (InputStream in = new FileInputStream("bild.png")) {
    int b;
    while ((b = in.read()) != -1) { /* b ist ein Byte 0-255 */ }
}

// Char-Stream: Textdatei zeilenweise lesen (mit Encoding)
try (BufferedReader br = Files.newBufferedReader(Path.of("text.txt"))) {
    String zeile;
    while ((zeile = br.readLine()) != null) { System.out.println(zeile); }
}

Das häufigste Klausur-Detail: woran erkennt die Schleife das Dateiende? Bei einem Byte-Stream liefert read() einen int zurück, das gelesene Byte (0 bis 255) oder -1, wenn nichts mehr kommt. -1, nicht 0, denn 0 ist ein gültiges Byte. Verfolge den Lese-Loop:

Lade Visualisierung...

Jeder ungepufferte read() löst potenziell einen Festplatten-Zugriff (System-Call) aus, byteweise ist das extrem langsam. Ein Buffer liest einen großen Block auf einmal in den Speicher; die folgenden read()-Aufrufe werden dann aus dem RAM bedient.

Lade Visualisierung...

Für die meisten Fälle reicht heute die knappe NIO-API aus java.nio.file:

// ganze Datei als String (kleine Dateien)
String inhalt = Files.readString(Path.of("text.txt"));        // UTF-8

// alle Zeilen als Liste
List<String> zeilen = Files.readAllLines(Path.of("text.txt"));

// schreiben
Files.writeString(Path.of("out.txt"), "Hallo");

// gepufferter Reader (grosse Dateien, zeilenweise)
try (BufferedReader br = Files.newBufferedReader(Path.of("gross.txt"))) { ... }

Files.readString / readAllLines laden die ganze Datei in den Speicher, ideal für kleine Dateien. Für große Dateien zeilenweise mit BufferedReader streamen.

1. Text → Char-Stream, Binär → Byte-Stream. Reader/Writer für .txt/.csv/.json, InputStream/OutputStream für Bilder, Audio, serialisierte Objekte.

2. EOF-Signale auseinanderhalten. Byte-read() liefert -1 am Ende, readLine() liefert null. Beides ist nicht 0 und nicht "" (leerer String).

3. Immer puffern. BufferedReader/BufferedInputStream macht aus vielen kleinen Festplatten-Zugriffen wenige große, oft drastisch schneller.

4. Encoding explizit setzen. Char-Streams wandeln Bytes über ein Charset (UTF-8). Ohne Angabe greift der Plattform-Default, das ist nicht portabel und zerschießt Umlaute.

5. Ressourcen mit try-with-resources schließen. Datei/Stream schließen, auch im Fehlerfall, sonst Resource-Leak.

6. NIO (Files/Path) für knappe Standard-Fälle. Files.readString, Files.readAllLines, Files.writeString ersetzen viel altes Boilerplate.

1. EOF-Bedingung falsch. while (in.read() != 0) statt != -1 läuft ewig oder bricht beim ersten Null-Byte ab. Bei readLine() ist die Bedingung != null, sonst NullPointerException.

2. Byte-Stream für Text. Direkt Bytes lesen und in chars casten ignoriert das Encoding, Mehrbyte-Zeichen (ä, ö, ü, Emojis) zerbrechen. Für Text immer Reader/Writer.

3. Nicht puffern. Byteweise von der Platte lesen ohne Buffer ist um Größenordnungen langsamer. Im Zweifel BufferedReader drumherum.

4. Datei nicht geschlossen. Ohne close() (oder try-with-resources) bleibt der File-Handle offen, Resource-Leak, bei vielen offenen Dateien "too many open files".

5. Encoding nicht angegeben. new FileReader(...) nutzt den Plattform-Default. Besser Files.newBufferedReader(path) (UTF-8) oder das Charset explizit angeben.

6. read() liefert int, nicht byte. Wer den Rückgabewert vorschnell in byte castet, kann -1 (EOF) nicht mehr von 255 unterscheiden. Erst auf -1 prüfen, dann casten.

Der Standard-Weg, eine Textdatei zu verarbeiten: gepufferter Reader, Zeile für Zeile, bis readLine() null liefert, und automatisch geschlossen per try-with-resources. Achte im Stepper auf das null-Signal (das Char-Pendant zum -1 der Byte-Streams).

Lade Visualisierung...

Klausur-Tipp: Zwei Fragen kommen fast immer: (1) "Wie erkennt die Schleife das Dateiende?" Antwort: read() → -1, readLine() → null. (2) "Warum BufferedReader?" Antwort: weniger Festplatten-Zugriffe (Buffer statt byteweise). Und: nenne try-with-resources fürs sichere Schließen.

Anmelden, um den Fortschritt zu speichern.

Nächster Schritt

Wenn du fertig bist: jetzt üben.

Aktives Abrufen festigt Wissen schneller als nochmal lesen.

War das hilfreich?

Verwandte Themen

  • Variablen und Datentypen
  • Bedingungen
  • Schleifen
  • Funktionen
  • Rekursion

Folgt

  • Serialisierung

Tools

Bald: Karteikarten · Spaced-Repetition · Mind-Map-Export

Fachliche Qualität
wird überarbeitetZuletzt geprüft am 12.06.2026

Diese Lerneinheit wurde für typische Bachelor-Klausuren konzipiert. So prüfen wir · Fehler entdeckt? Melde ihn uns oder markiere die fragliche Stelle direkt im Text oben.

Klausur-ÜbersichtKomplette Übersicht: alle Tabs als linearer Text zum Lernen
▾

Alle Tabs der Lerneinheit (Erklärung · Interaktiv verstehen · Praxis-Übung · Klausur-Quiz) als durchgehender Text. Ideal zum Wiederholen vor der Klausur, und für Suchmaschinen wie Google, Bing und KI-Suche (ChatGPT, Perplexity).

Inhalt dieser Übersicht

  1. Erklärung(Erklärung)
  2. Interaktiv verstehen(Visualisierung / Interaktiv)
  3. Praxis-Übung(Quiz / Klausurfragen)
  4. Klausur-Quiz(Quiz / Klausurfragen)
Teil 1·Erklärung

Erklärung

Sobald dein Programm mit der Außenwelt redet, eine Datei liest, eine schreibt, übers Netzwerk kommuniziert, läuft das über Streams: einen Fluss von Daten, der Stück für Stück gelesen oder geschrieben wird. Java trennt dabei sauber zwischen Byte-Strömen (für Binärdaten) und Zeichen-Strömen (für Text). Wer das verwechselt, bekommt kaputte Umlaute oder unnötig komplizierten Code.

Was du können musst:

  • Byte-Streams (InputStream/OutputStream) von Char-Streams (Reader/Writer) unterscheiden
  • das Lese-Muster mit dem EOF-Signal kennen (read() liefert -1, readLine() liefert null)
  • Buffering verstehen (warum BufferedReader schneller ist)
  • Dateien sicher schließen (try-with-resources) und das richtige Encoding (UTF-8) wählen

Abgrenzung: hier die Grundlagen der Datei-I/O. Tiefes NIO (Channels, Buffers, Memory-Mapped Files, asynchrones I/O) ist Vertiefung.

Die Idee in einem Satz

Ein Stream ist ein Datenfluss: InputStream/Reader liest Daten herein, OutputStream/Writer schreibt hinaus, Stück für Stück, bis das Ende (EOF) erreicht ist.

Byte-Streams vs. Char-Streams

Byte-StreamsChar-Streams
BasisklassenInputStream, OutputStreamReader, Writer
EinheitByte (0-255)Zeichen (mit Encoding)
WofürBinärdaten: Bilder, Audio, serialisierte ObjekteText: .txt, .csv, .json
EOF-Signalread() liefert -1readLine() liefert null

Faustregel: Text → Char-Stream (Reader/Writer), alles andere → Byte-Stream. Ein Char-Stream wandelt Bytes über ein Encoding (Charset, meist UTF-8) in Zeichen um; ein Byte-Stream tut das nicht.

// Byte-Stream: Datei roh als Bytes lesen
try (InputStream in = new FileInputStream("bild.png")) {
    int b;
    while ((b = in.read()) != -1) { /* b ist ein Byte 0-255 */ }
}

// Char-Stream: Textdatei zeilenweise lesen (mit Encoding)
try (BufferedReader br = Files.newBufferedReader(Path.of("text.txt"))) {
    String zeile;
    while ((zeile = br.readLine()) != null) { System.out.println(zeile); }
}

Das Lese-Muster und das EOF-Signal

Das häufigste Klausur-Detail: woran erkennt die Schleife das Dateiende? Bei einem Byte-Stream liefert read() einen int zurück, das gelesene Byte (0 bis 255) oder -1, wenn nichts mehr kommt. -1, nicht 0, denn 0 ist ein gültiges Byte. Verfolge den Lese-Loop:

Interaktive Visualisierung

Interaktive Komponente: probiere sie im Topic-Player oben aus.

Buffering: warum BufferedReader

Jeder ungepufferte read() löst potenziell einen Festplatten-Zugriff (System-Call) aus, byteweise ist das extrem langsam. Ein Buffer liest einen großen Block auf einmal in den Speicher; die folgenden read()-Aufrufe werden dann aus dem RAM bedient.

Interaktive Visualisierung

Interaktive Komponente: probiere sie im Topic-Player oben aus.

Moderne I/O: NIO (Files / Path)

Für die meisten Fälle reicht heute die knappe NIO-API aus java.nio.file:

// ganze Datei als String (kleine Dateien)
String inhalt = Files.readString(Path.of("text.txt"));        // UTF-8

// alle Zeilen als Liste
List<String> zeilen = Files.readAllLines(Path.of("text.txt"));

// schreiben
Files.writeString(Path.of("out.txt"), "Hallo");

// gepufferter Reader (grosse Dateien, zeilenweise)
try (BufferedReader br = Files.newBufferedReader(Path.of("gross.txt"))) { ... }

Files.readString / readAllLines laden die ganze Datei in den Speicher, ideal für kleine Dateien. Für große Dateien zeilenweise mit BufferedReader streamen.

Klausur-Faustregeln

1. Text → Char-Stream, Binär → Byte-Stream. Reader/Writer für .txt/.csv/.json, InputStream/OutputStream für Bilder, Audio, serialisierte Objekte.

2. EOF-Signale auseinanderhalten. Byte-read() liefert -1 am Ende, readLine() liefert null. Beides ist nicht 0 und nicht "" (leerer String).

3. Immer puffern. BufferedReader/BufferedInputStream macht aus vielen kleinen Festplatten-Zugriffen wenige große, oft drastisch schneller.

4. Encoding explizit setzen. Char-Streams wandeln Bytes über ein Charset (UTF-8). Ohne Angabe greift der Plattform-Default, das ist nicht portabel und zerschießt Umlaute.

5. Ressourcen mit try-with-resources schließen. Datei/Stream schließen, auch im Fehlerfall, sonst Resource-Leak.

6. NIO (Files/Path) für knappe Standard-Fälle. Files.readString, Files.readAllLines, Files.writeString ersetzen viel altes Boilerplate.

Häufige Stolpersteine

1. EOF-Bedingung falsch. while (in.read() != 0) statt != -1 läuft ewig oder bricht beim ersten Null-Byte ab. Bei readLine() ist die Bedingung != null, sonst NullPointerException.

2. Byte-Stream für Text. Direkt Bytes lesen und in chars casten ignoriert das Encoding, Mehrbyte-Zeichen (ä, ö, ü, Emojis) zerbrechen. Für Text immer Reader/Writer.

3. Nicht puffern. Byteweise von der Platte lesen ohne Buffer ist um Größenordnungen langsamer. Im Zweifel BufferedReader drumherum.

4. Datei nicht geschlossen. Ohne close() (oder try-with-resources) bleibt der File-Handle offen, Resource-Leak, bei vielen offenen Dateien "too many open files".

5. Encoding nicht angegeben. new FileReader(...) nutzt den Plattform-Default. Besser Files.newBufferedReader(path) (UTF-8) oder das Charset explizit angeben.

6. read() liefert int, nicht byte. Wer den Rückgabewert vorschnell in byte castet, kann -1 (EOF) nicht mehr von 255 unterscheiden. Erst auf -1 prüfen, dann casten.

Teil 2·Visualisierung / Interaktiv

Interaktiv verstehen

Eine Textdatei zeilenweise lesen

Der Standard-Weg, eine Textdatei zu verarbeiten: gepufferter Reader, Zeile für Zeile, bis readLine() null liefert, und automatisch geschlossen per try-with-resources. Achte im Stepper auf das null-Signal (das Char-Pendant zum -1 der Byte-Streams).

Interaktive Visualisierung

Interaktive Komponente: probiere sie im Topic-Player oben aus.

Klausur-Tipp: Zwei Fragen kommen fast immer: (1) "Wie erkennt die Schleife das Dateiende?" Antwort: read() → -1, readLine() → null. (2) "Warum BufferedReader?" Antwort: weniger Festplatten-Zugriffe (Buffer statt byteweise). Und: nenne try-with-resources fürs sichere Schließen.

Teil 3·Quiz / Klausurfragen

Praxis-Übung

Klausurfragen mit Lösungen (6)

F1.Welche Stream-Art nutzt man, um eine Textdatei (.txt) zeilenweise zu lesen?

Antwort: Reader / BufferedReader (Char-Stream)

Erklärung: Fuer Text nutzt man Char-Streams (Reader/BufferedReader): sie wandeln Bytes ueber ein Encoding (UTF-8) in Zeichen. Byte-Streams (InputStream) sind fuer Binaerdaten und kennen kein Encoding, Umlaute wuerden zerbrechen.

F2.Was liefert die Byte-Methode read() zurück, wenn das Dateiende erreicht ist?

Antwort: -1

Erklärung: read() liefert das naechste Byte (0-255) oder -1 bei EOF. NICHT 0 (das ist ein gueltiges Byte) und nicht null (read gibt einen int zurueck). Das Char-Pendant readLine() liefert dagegen null bei EOF.

F3.BufferedReader ist hauptsächlich schneller, weil er weniger Festplatten-Zugriffe macht.

Antwort: Wahr

Erklärung: Richtig. Statt pro Byte/Zeichen einen Festplatten-Zugriff (Syscall) zu machen, liest der Puffer einen grossen Block auf einmal und bedient die folgenden read()-Aufrufe aus dem Speicher. Oft Faktor 10-100 schneller.

Typ: Wahr/Falsch

F4.Was ist der Hauptgrund, Datei-Operationen in try-with-resources zu kapseln?

Antwort: Die Datei wird automatisch geschlossen, auch wenn eine Exception fliegt

Erklärung: try-with-resources ruft close() automatisch auf, am Ende des Blocks und auch im Fehlerfall. Das verhindert Resource-Leaks (offene File-Handles). Mit Performance, Encoding oder Buffering hat es nichts zu tun.

F5.Ordne jede Klasse ihrer Aufgabe zu.

Zuordnungen:

  • InputStream → Bytes lesen (binär)
  • Reader → Zeichen lesen (Text, mit Encoding)
  • BufferedReader → gepuffertes zeilenweises Lesen
  • OutputStream → Bytes schreiben (binär)

Erklärung: InputStream/OutputStream = Bytes (binär), Reader/Writer = Zeichen (Text). BufferedReader puffert und bietet readLine().

Typ: Zuordnung

F6.Warum ist es ein Fehler, den Rückgabewert von read() sofort in ein byte zu casten?
byte b;
while ((b = (byte) in.read()) != -1) { ... }

Antwort: Ein Byte 255 wird als (byte) zu -1, dann bricht die Schleife fälschlich beim Wert 255 ab

Erklärung: read() gibt absichtlich einen int (0-255 oder -1) zurueck, damit EOF (-1) von jedem gueltigen Byte unterscheidbar ist. Castet man zu byte, wird 255 zu -1 (byte ist signed, -128..127), und die Schleife bricht beim Datenbyte 255 faelschlich ab. Erst auf -1 pruefen, dann casten.

Teil 4·Quiz / Klausurfragen

Klausur-Quiz

Klausurfragen mit Lösungen (6)

F1.Womit signalisiert readLine() (Char-Stream) das Dateiende?

Antwort: null

Erklärung: readLine() liefert die naechste Zeile als String oder null bei EOF. Ein leerer String ("") ist eine gueltige Leerzeile, NICHT das Ende. Byte-read() nutzt dagegen -1.

F2.Welche Methode lädt eine ganze (kleine) Textdatei in einem Aufruf als String?

Antwort: Files.readString(path)

Erklärung: Files.readString(path) liest die komplette Datei als String (UTF-8), ideal fuer kleine Dateien. Fuer grosse Dateien besser zeilenweise mit BufferedReader streamen, statt alles in den Speicher zu laden.

F3.Ein Byte-Stream (InputStream) eignet sich gut, um eine Textdatei mit Umlauten zu lesen.

Antwort: Falsch

Erklärung: Falsch. Ein Byte-Stream kennt kein Encoding. Mehrbyte-Zeichen wie ä/ö/ü (in UTF-8 mehrere Bytes) zerbrechen, wenn man sie byteweise als Zeichen interpretiert. Fuer Text nimmt man Char-Streams (Reader), die ueber ein Charset dekodieren.

Typ: Wahr/Falsch

F4.Für Binärdaten nutzt man {{1}}-Streams, für Text {{2}}-Streams. Das Lese-Ende signalisiert read() mit {{3}} und readLine() mit {{4}}.

Lösungen pro Lücke:

  • {{1}}: Byte / byte
  • {{2}}: Char / Zeichen / char
  • {{3}}: -1
  • {{4}}: null

Erklärung: Byte-Streams (binär) vs. Char-Streams (Text). EOF: read() liefert -1, readLine() liefert null. Standard-Klausurwissen der Datei-I/O.

Typ: Lückentext

F5.Warum sollte man das Encoding (z.B. UTF-8) beim Lesen einer Textdatei explizit angeben?

Antwort: Sonst wird der Plattform-Default benutzt, was nicht portabel ist und Umlaute zerstören kann

Erklärung: Ohne explizites Charset nimmt Java den Plattform-Default (z.B. Windows-1252 vs. UTF-8). Dieselbe Datei wird dann auf verschiedenen Systemen unterschiedlich dekodiert, Umlaute und Sonderzeichen zerbrechen. Files.newBufferedReader nutzt standardmaessig UTF-8.

F6.Was ist an dieser Schleife problematisch?
FileReader fr = new FileReader("daten.txt");
int c;
while ((c = fr.read()) != 0) {
    System.out.print((char) c);
}

Antwort: Die Bedingung != 0 ist falsch: EOF ist -1, nicht 0; ausserdem wird die Datei nie geschlossen

Erklärung: Zwei Fehler: (1) Das EOF-Signal von read() ist -1, nicht 0, die Bedingung muss != -1 lauten (mit != 0 laeuft die Schleife ueber das Dateiende hinaus weiter). (2) fr wird nie geschlossen, Resource-Leak. Besser: try-with-resources + != -1.

Zur KategorieProgrammiergrundlagen.Mehr Themen entdeckenZum Themen-Hub.

UniProMax ist eine themenbasierte Lernplattform für Studierende an deutschen Unis.

Wir glauben, dass Verstehen besser ist als Auswendiglernen. Wir bauen Lerneinheiten die zeigen statt erzählen. Code, Visualisierung, Quiz. Auf Deutsch.

Marke

UniProMaxUniProMax

Themenbasiert, visuell, interaktiv.

Inhalte

  • Alle Themen (Hub)
  • Programmiergrundlagen
  • Algorithmen
  • Mathematik
  • Statistik
  • Datenbanken
  • Rechnungswesen
  • VWL

Studiengang-Filter

  • Informatik
  • Wirtschaftsinformatik
  • BWL
  • Data Science
  • VWL
  • Wirtschaftsingenieurwesen
  • Mathe
  • Psychologie
  • weitere Studiengänge folgen

Plattform

  • Mein Fortschritt
  • Impressum
  • Datenschutz
© 2026 UniProMaxAlle Systeme onlinev0.2 / Sommersemester 2026
UniProMaxUniProMaxUniProMaxUniProMax