CodeGym /Java-Blog /Random-DE /Eingabe/Ausgabe in Java. FileInputStream-, FileOutputStre...
Autor
Alex Vypirailenko
Java Developer at Toshiba Global Commerce Solutions

Eingabe/Ausgabe in Java. FileInputStream-, FileOutputStream- und BufferedInputStream-Klassen

Veröffentlicht in der Gruppe Random-DE
"Hallo! In der heutigen Lektion werden wir unser Gespräch über Eingabe- und Ausgabeströme in Java ( Java I/O ) fortsetzen. Dies ist nicht die erste Lektion zu diesem Thema und es wird sicherlich nicht die letzte sein :) Eingabe/Ausgabe in Java.  FileInputStream-, FileOutputStream- und BufferedInputStream-Klassen – 1Wie es ist Wenn es passiert, bietet die Java-Sprache viele Möglichkeiten, mit I/O zu arbeiten. Es gibt eine ganze Reihe von Klassen, die diese Funktionalität implementieren, daher haben wir sie in mehrere Lektionen unterteilt – damit Sie nicht gleich zu Beginn verwirrt sind :) In der Vergangenheit In den Lektionen haben wir BufferedReader, sowie die Klassen InputStreamund abstract und mehrere Nachkommen angesprochen OutputStream. Heute betrachten wir drei neue Klassen: FileInputStream,  FileOutputStream, und  BufferedInputStream.

Die FileOutputStream-Klasse

Der Hauptzweck der FileOutputStreamKlasse besteht darin, Bytes in eine Datei zu schreiben. Nichts Kompliziertes :) FileOutputStreamist eine der Implementierungen der OutputStreamabstrakten Klasse. Im Konstruktor nehmen Objekte dieser Klasse entweder den Pfad zur Zieldatei (in die die Bytes geschrieben werden sollen) oder ein FileObjekt an. Wir werden jeweils Beispiele untersuchen:

public class Main { 

   public static void main(String[] args) throws IOException { 

       File file = new File("C:\\Users\\Username\\Desktop\\test.txt"); 
       FileOutputStream fileOutputStream = new FileOutputStream(file); 

       String greetings = "Hi! Welcome to CodeGym — The best site for would-be programmers!"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
}
Beim Erstellen des FileObjekts haben wir den gewünschten Pfad an den Konstruktor übergeben. Wir müssen es nicht im Voraus erstellen: Wenn es nicht existiert, wird es vom Programm erstellt. Sie können auch ohne die Erstellung eines zusätzlichen Objekts auskommen, indem Sie einfach einen String mit dem Pfad übergeben:

public class Main { 

    public static void main(String[] args) throws IOException { 

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt"); 
       String greetings = "Hi! Welcome to CodeGym — The best site for would-be programmers!"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
} 
Das Ergebnis wird in beiden Fällen das gleiche sein. Wir können unsere Datei öffnen und dort Folgendes sehen:

Hi! Welcome to CodeGym — The best site for would-be programmers!
Aber hier gibt es eine Nuance. Versuchen Sie, den Code aus dem obigen Beispiel mehrmals hintereinander auszuführen. Schauen Sie dann in die Datei und beantworten Sie diese Frage: Wie viele Zeilen hat sie? Nur einer. Aber Sie haben den Code mehrmals ausgeführt. Es stellt sich heraus, dass die Daten jedes Mal überschrieben werden – die alten werden durch die neuen ersetzt. Was machen wir, wenn uns das nicht passt und wir nacheinander in die Datei schreiben müssen? Was wäre, wenn wir unsere Begrüßung dreimal hintereinander in eine Datei schreiben möchten? Es ist alles sehr einfach. Da die Sprache nicht wissen kann, welches Verhalten wir jeweils benötigen, FileOutputStreamkann der Konstruktor einen zusätzlichen Parameter verwenden:boolean append. Wenn der Wert wahr ist, werden die Daten an das Ende der Datei geschrieben. Wenn es falsch ist (und standardmäßig falsch ist), werden alle alten Daten gelöscht und durch neue Daten ersetzt. Lassen Sie uns dies überprüfen, indem wir unseren geänderten Code dreimal ausführen:

public class Main { 

   public static void main(String[] args) throws IOException { 

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true); 
       String greetings = "Hi! Welcome to CodeGym — The best site for would-be programmers!\r\n"; 

       fileOutputStream.write(greetings.getBytes()); 
       fileOutputStream.close(); 
   } 
} 
Dateiinhalt:

Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers! 
Hi! Welcome to CodeGym — The best site for would-be programmers!
Das ist jetzt anders! Vergessen Sie diese Funktion nicht, wenn Sie I/O-Klassen verwenden. Es gab eine Zeit, in der ich stundenlang Aufgaben erledigte, mir stundenlang den Kopf zerbrach und versuchte zu verstehen, wie meine Daten aus den Dateien verschwanden :) Und natürlich, genau wie bei anderen I/O-Klassen, vergessen Sie nicht, die Methode zu close()verwenden um Ressourcen freizugeben.

Die FileInputStream-Klasse

Das FileInputStreamhat den gegenteiligen Zweck – das Lesen von Bytes aus einer Datei. Ebenso wie FileOutputStreaminherits OutputStreamleitet sich diese Klasse von der InputStreamabstrakten Klasse ab. Wir schreiben ein paar Zeilen Text in unsere Datei „ test.txt “:

"So close no matter how far 
Couldn't be much more from the heart 
Forever trusting who we are 
And nothing else matters"
Eingabe/Ausgabe in Java.  FileInputStream-, FileOutputStream- und BufferedInputStream-Klassen – 2So sieht es aus, Daten aus einer Datei zu lesen mit FileInputStream:

public class Main { 

   public static void main(String[] args) throws IOException { 

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt"); 

       int i; 

       while((i=fileInputStream.read())!= -1){ 

           System.out.print((char)i); 

       } 
   } 
}
Wir lesen ein Byte aus der Datei, wandeln die gelesenen Bytes in Zeichen um und zeigen sie auf der Konsole an. Und hier ist die Konsolenausgabe:

So close no matter how far 
Couldn't be much more from the heart 
Forever trusting who we are 
And nothing else matters

Die BufferedInputStream-Klasse

Ich denke, angesichts des Wissens aus früheren Lektionen kann man leicht sagen, warum wir die Klasse brauchen BufferedInputStreamund welche Vorteile sie im Vergleich dazu hat FileInputStream:) Wir sind bereits auf gepufferte Streams gestoßen, also versuchen Sie es zu erraten (oder sich daran zu erinnern), bevor Sie weiterlesen :) Gepufferte Streams werden hauptsächlich zur Optimierung von I/O benötigt. Der Zugriff auf eine Datenquelle, beispielsweise das Lesen aus einer Datei, ist im Hinblick auf die Leistung ein kostspieliger Vorgang. Und der Zugriff auf eine Datei zum Lesen jedes Bytes ist verschwenderisch. Aus diesem Grund BufferedInputStreamliest es Daten nicht byteweise, sondern blockweise und speichert sie vorübergehend in einem speziellen Puffer. Dadurch können wir das Programm optimieren, indem wir die Anzahl der Zugriffe auf die Datei reduzieren. Mal sehen, wie das aussieht:

public class Main { 

   public static void main(String[] args) throws IOException { 

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt"); 

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200); 

       int i; 

       while((i = bufferedInputStream.read())!= -1){ 

           System.out.print((char)i); 
       } 
   } 
} 
Hier haben wir ein BufferedInputStreamObjekt erstellt. Sein Konstruktor übernimmt eine Instanz der InputStreamKlasse oder eines ihrer Nachkommen, was auch FileInputStreamder Fall ist. Als zusätzliches Argument wird die Puffergröße in Bytes verwendet. Dank dieses Arguments werden die Daten nun nicht Byte für Byte, sondern jeweils 200 Byte aus der Datei gelesen! Stellen Sie sich vor, wie stark wir die Anzahl der Dateizugriffe reduziert haben. Um die Leistung zu vergleichen, können Sie eine große Textdatei (mehrere Megabyte Text) nehmen und vergleichen, wie lange es in Millisekunden dauert, sie mit und zu lesen und an die Konsole FileInputStreamauszugeben BufferedInputStream. Hier ist Code, der beide Optionen demonstriert:

public class Main { 

   public static void main(String[] args) throws IOException { 

       Date date = new Date(); 

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf"); 
       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); 

       int i; 
       while((i = bufferedInputStream.read())!= -1){ 

           System.out.print((char)i); 
       } 

       Date date1 = new Date(); 
       System.out.println((date1.getTime() - date.getTime())); 
   } 
} 

 
public class Main { 

   public static void main(String[] args) throws IOException { 

       Date date = new Date(); 
       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf"); 

       int i; 
       while((i = fileInputStream.read())!= -1){ 

           System.out.print((char)i); 
       } 


       Date date1 = new Date(); 
       System.out.println((date1.getTime() - date.getTime())); 
   }
}
Beim Lesen einer 1,5-MB-Datei auf meinem Computer FileInputStreamwar die Arbeit in ca. 3500 Millisekunden abgeschlossen, aber BufferedInputStreamin ca. 1700 Millisekunden erledigt. Wie Sie sehen, hat der gepufferte Stream die Arbeit optimiert und halbiert! :) Wir werden weiterhin I/O-Kurse studieren – bis bald!
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION