Die wichtigste Funktion eines Computers ist die Verarbeitung von Daten. Eine nützliche Computersprache muss über gute E/A-Fähigkeiten verfügen, damit unverarbeitete Daten in das Programm fließen und verarbeitete Daten herausfließen.
Im Vergleich zu anderen Sprachen sind die E/A-Funktionen von Java komplex. In anderen Sprachen sind viele E/A-Funktionen (z. B. das Lesen von Dateien) gekapselt und können mit einer oder zwei Programmzeilen implementiert werden. In Java benötigen Programmierer oft mehrere Dekorationsebenen, um das Lesen von Dateien zu erreichen.
Der Vorteil der relativen Komplexität ist die Flexibilität von IO. In Java können Programmierer den gesamten IO-Prozess steuern, um die beste IO-Methode zu entwerfen. Wir werden weiter unten mehr sehen.
IO-Beispiel
Unten ist die Datei file.txt, die ich zur Demonstration verwendet habe
Hallo Welt! Hallo Nerd!
Schauen wir uns zunächst ein Beispiel für das Lesen von Dateien an:
import java.io.*;public class Test{ public static void main(String[] args) { try { BufferedReader br = new BufferedReader(new FileReader("file.txt")); while (line != null) { System.out.println(line); line = br.readLine( } br.close( ); e) { System.out.println("IO Problem" } }}
Dieses Programm enthält einen try...catch...finally-Ausnahmebehandler. Weitere Informationen zur Ausnahmebehandlung finden Sie im Java Advanced Tutorial
Dekore und Funktionskombinationen
Der Schlüssel zum Programmieren von E/A besteht darin, ein BufferedReader-Objekt br zu erstellen:
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
Während des Erstellungsprozesses haben wir zunächst ein FileReader-Objekt erstellt. Die Funktion dieses Objekts besteht darin, den Bytestream aus der Datei „file.txt“ zu lesen und in einen Textstream umzuwandeln. In Java ist die Standardtextcodierung Unicode. BufferedReader() empfängt das FileReader-Objekt, erweitert die Funktionen von FileReader und erstellt ein neues BufferedReader-Objekt. Zusätzlich zu den oben genannten Funktionen zum Lesen und Konvertieren von Dateien bietet dieses Objekt auch zwischengespeicherte (gepufferte) Lesefunktionen. Schließlich können wir die Datei Zeile für Zeile lesen, indem wir die Methode readLine() für das br-Objekt aufrufen.
(Beim Cache-Lesen wird ein Bereich im Speicher als Cache geöffnet, in dem der von FileReader gelesene Textstrom gespeichert wird. Wenn der Cache-Inhalt gelesen wird (z. B. der Befehl readLine (), lädt der Cache den nachfolgenden Textstrom.)
BufferedReader() ist ein Dekorator, der ein primitives Objekt empfängt und ein dekoriertes Objekt mit komplexeren Funktionen zurückgibt. Der Vorteil von Dekorateuren besteht darin, dass mit ihnen unterschiedliche Objekte dekoriert werden können. Was wir hier ändern, ist der aus der Datei gelesene Textstrom. Andere Textströme wie Standardeingaben, Netzwerkübertragungsströme usw. können durch BufferedReader() geändert werden, um zwischengespeichertes Lesen zu erreichen.
Das folgende Diagramm zeigt, wie br funktioniert, wobei der Datenfluss von unten nach oben erfolgt:
Der obige Dekorationsprozess ist der Textstream-Idee unter Linux sehr ähnlich. Unter Linux verwenden wir einen funktionsähnlichen Ansatz zur Verarbeitung und Weitergabe von Textströmen. In Java verwenden wir Dekoratoren. Ihre Ziele sind jedoch ähnlich: Modularisierung und freie Kombination von Funktionen sollen erreicht werden.
mehr Kombinationen
Tatsächlich bietet Java eine große Auswahl an Dekoratoren. FileReader kombiniert die beiden Schritte Lesen und Konvertieren und übernimmt häufig verwendete Standardeinstellungen, wie z. B. Unicode für die Kodierung. Wir können die Kombination von FileInputStream + InputStreamReader verwenden, um FileReader zu ersetzen und so die beiden Schritte des Lesens von Bytes und des Konvertierens zu trennen und eine bessere Kontrolle über die beiden Prozesse zu haben.
(Natürlich ist FileReader bequemer zu verwenden. InputStreamReader konvertiert FileInputStream in einen Reader für die Verarbeitung von Unicode-Text.)
Pfeile geben die Richtung des Datenflusses an
Das Lesen und Schreiben von Streams erfolgt aus vier Basisklassen: InputStream, OutputStream, Reader und Writer. InputStream und Reader verarbeiten Lesevorgänge und OutputStream und Writer verarbeiten Schreibvorgänge. Sie befinden sich beide im Paket java.io. Die Vererbungsbeziehung ist wie folgt:
java.io
Darüber hinaus verfügt IOException über die folgenden abgeleiteten Klassen:
IOException
Reader und Writer und ihre abgeleiteten Klassen verarbeiten Unicode-Text. Wie wir Buffered Reader, InputStreamReader oder FileReader sehen.
InputStream und OutputStream und ihre abgeleiteten Klassen verarbeiten Byteströme. Die Daten im Computer können in Byteform betrachtet werden, sodass InputStream und OutputStream zur Verarbeitung eines größeren Datenbereichs verwendet werden können. Beispielsweise können wir die folgende Kombination verwenden, um die in der komprimierten Datei enthaltenen Daten (z. B. Ganzzahlen) zu lesen:
Pfeile geben die Richtung des Datenflusses an
Wir lesen den Bytestrom aus der komprimierten Datei, dekomprimieren ihn dann und lesen schließlich die Daten.
schreiben
Schreibvorgänge ähneln Lesevorgängen. Durch den Einsatz von Dekorationen können wir komplexe Schreibfunktionen umsetzen. Hier ist ein einfaches Beispiel für das Schreiben von Text:
import java.io.*;public class Test{ public static void main(String[] args) { try { String content = "Vielen Dank für Ihren Fisch."; / die Datei erstellen, wenn sie nicht existiert if (!file.exists()) { file.createNewFile( } FileWriter fw = new FileWriter(file.getAbsoluteFile()); BufferedWriter bw = new BufferedWriter(fw); bw.close(); } Catch(IOException e) { System.out.println("IO Problem" }}
Das Dateiobjekt wird oben für die Verarbeitung von Dateipfaden erstellt.
Zusammenfassen
Dies ist nur eine grundlegende Einführung in Java IO. Javas IO ist relativ komplex. Java-Programmierer müssen sich etwas Zeit nehmen, um sich mit den Klassen in java.io und ihrer Funktionalität vertraut zu machen.