Wie man eine Datei in einen Java-String einliest: Analyse unter der Haube

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Wie man eine Datei in einen Java-String einliest: Analyse einer häufig gestellten Frage von Stack Overflow

\n\n

Wenn Sie sich jemals gefragt haben: „How do I create a Java string from the contents of a file?“ – sind Sie nicht allein. Diese Frage hat auf Stack Overflow tausende Aufrufe erhalten, und das aus gutem Grund. Was scheinbar eine banale Operation ist – eine Textdatei einlesen und ihren Inhalt in einen String speichern – birgt viele Fallstricke: von Speicherlecks bis hin zu Problemen mit der Kodierung.

\n\n

In diesem Artikel geben wir nicht nur fertige Rezepte. Wir schauen unter die Haube jeder Methode: wie BufferedReader funktioniert, warum Files.readString() erst in Java 11 erschienen ist und wie sich Scanner von InputStream unterscheidet. Los geht's!

\n\n

Warum ist das schwieriger, als es scheint?

\n\n

Auf den ersten Blick ist die Aufgabe trivial: Es gibt eine Datei, es gibt einen String. Aber Java ist eine Sprache mit strenger Typisierung und verwaltetem Speicher. Um eine Datei einzulesen, muss man:

\n\n
    \n
  • Einen Datenstrom öffnen (InputStream, Reader)
  • \n
  • Das Lesen puffern (um nicht bei jedem Byte auf die Festplatte zuzugreifen)
  • \n
  • Bytes/Zeichen in einem gemeinsamen Puffer sammeln
  • \n
  • Unter Berücksichtigung der Kodierung in einen String umwandeln
  • \n
  • Ressourcen schließen (um Speicherlecks bei Dateideskriptoren zu vermeiden)
  • \n
\n\n

Jeder dieser Schritte ist ein potenzieller Fehlerpunkt. Lassen Sie uns die gängigsten Ansätze durchgehen.

\n\n

Methode 1: Der Klassiker – BufferedReader (Java 1.1+)

\n\n

Die älteste und bewährteste Methode. Verwendet BufferedReader zum zeilenweisen Lesen. Unter der Haube sammelt ein Puffer (standardmäßig 8 KB) Daten, wodurch die Anzahl der Systemaufrufe von read() reduziert wird.

\n\n
public static String readFileBufferedReader(String filePath) throws IOException {\n    StringBuilder content = new StringBuilder();\n    try (BufferedReader reader = new BufferedReader(new FileReader(filePath, StandardCharsets.UTF_8))) {\n        String line;\n        while ((line = reader.readLine()) != null) {\n            content.append(line).append(System.lineSeparator());\n        }\n    }\n    return content.toString();\n}
\n\n

Wie funktioniert das unter der Haube?

\n

FileReader öffnet die Datei und erstellt einen FileInputStream. BufferedReader umschließt diesen und fügt einen Puffer hinzu. Beim Aufruf von readLine() wird ein Datenblock (z. B. 8 KB) gelesen und die Zeile aus dem Puffer zusammengesetzt. Ist die Zeile länger als der Puffer, wird der Puffer erneut gelesen. try-with-resources stellt sicher, dass der Stream auch bei einer Ausnahme geschlossen wird.

\n\n

Vorteile: Funktioniert in jeder Java-Version, kontrolliertes zeilenweises Lesen.
\nNachteile: Fügt am Ende ein zusätzliches Zeilentrennzeichen hinzu, ineffizient für sehr große Dateien (String im Speicher).

\n\n

Methode 2: Scanner – bequem, aber langsam (Java 5+)

\n\n

Viele mögen Scanner wegen seiner Einfachheit. Er kann Eingaben in Tokens aufteilen, wird aber zum Lesen einer gesamten Datei wie folgt verwendet:

\n\n
public static String readFileScanner(String filePath) throws IOException {\n    try (Scanner scanner = new Scanner(new File(filePath), StandardCharsets.UTF_8.name())) {\n        scanner.useDelimiter("\\\\A"); // Dateianfang als Trennzeichen\n        return scanner.hasNext() ? scanner.next() : "";\n    }\n}
\n\n

Die Magie von \\\\A: Dies ist ein regulärer Ausdruck, der den Anfang der Eingabedaten kennzeichnet. Indem wir ihn als Trennzeichen setzen, zwingen wir Scanner, den gesamten Inhalt auf einmal zu lesen. Unter der Haube verwendet Scanner Pattern, um das Trennzeichen zu finden, was zusätzlichen Aufwand für reguläre Ausdrücke verursacht.

\n\n

Vorteile: Sehr prägnanter Code.
\nNachteile: Langsamer als BufferedReader aufgrund der Arbeit mit regulären Ausdrücken, nicht für Binärdateien geeignet.

\n\n

Methode 3: Files.readAllLines() – Komfort von Java 8 (NIO)

\n\n

Ab Java 8 bot das Paket java.nio.file eine elegante

Blogs

Buchempfehlungen