„Hallo Amigo! Heute werden wir uns noch einmal damit befassen, wie InputStream und OutputStream funktionieren. Die erste Erklärung war schon ein wenig vereinfachend. Dies sind keine Interfaces. Es handelt sich um abstrakte Klassen, und sie haben sogar einige implementierte Methoden. Sehen wir uns ihre Methoden einmal an:“
InputStream-Methoden | Das tut die Methode |
---|---|
|
Diese Methode liest sofort einen Block von Bytes in den Puffer (byte-Array), bis der Puffer voll ist oder bis die Quelle keine Bytes mehr zum Lesen hat. Die Methode gibt die Anzahl der tatsächlich gelesenen Bytes zurück (die kleiner als die Länge des Arrays sein kann). |
|
Diese Methode liest ein Byte und gibt es zurück. Das Ergebnis wird zu einem int erweitert. Wenn keine Bytes mehr zum Lesen vorhanden sind, gibt die Methode -1 zurück. |
|
Diese Methode gibt die Anzahl der ungelesenen (verfügbaren) Bytes zurück. |
|
Diese Methode „schließt“ den Datenstrom. Du rufst sie auf, wenn du die Arbeit mit dem Stream beendet hast. Das Objekt führt dann die notwendigen Operationen aus, um die Datei zu schließen usw. Zu diesem Zeitpunkt kannst du keine Daten mehr aus dem Stream lesen. |
„Wir können also nicht nur einzelne Bytes lesen, sondern auch ganze Blöcke lesen?“
„Exakt.“
„Können wir auch ganze Blöcke schreiben?“
„Ja, sieh dir das an:“
OutputStream-Methoden | Das tut die Methode |
---|---|
|
Diese Methode schreibt ein Byte. Der Typ int wird auf ein Byte eingeschränkt. Der zusätzliche Teil wird einfach verworfen. |
|
Diese Methode schreibt einen Block von Bytes. |
|
Diese Methode schreibt einen Teil eines Blocks von Bytes. Sie wird in Fällen verwendet, in denen das Byte-Array möglicherweise nicht vollständig gefüllt ist. |
|
Wenn der Datenstrom intern noch nicht geschriebene Daten speichert, erzwingt diese Methode den Schreibvorgang. |
|
Diese Methode „schließt“ den Datenstrom. Du rufst sie auf, wenn du die Arbeit mit dem Stream beendet hast. Das Objekt führt dann die notwendigen Operationen aus, um die Datei zu schließen usw. Du kannst keine Daten mehr in den Stream schreiben, und flush wird automatisch aufgerufen. |
„Wie würde der Code zum Kopieren von Dateien aussehen, wenn wir ganze Blöcke auf einmal lesen würden, statt einzelner Bytes?“
„Hmm. So etwa:“
public static void main(String[] args) throws Exception
{
//Create a stream to read bytes from a file
FileInputStream inputStream = new FileInputStream("c:/data.txt");
//Create a stream to write bytes to a file
FileOutputStream outputStream = new FileOutputStream("c:/result.txt");
byte[] buffer = new byte[1000];
while (inputStream.available() > 0) //as long as there are unread bytes
{
//Read the next block of bytes into buffer, and store the actual number of bytes read in count.
int count = inputStream.read(buffer);
outputStream.write(buffer, 0, count); //Write a block (part of a block) to the second stream
}
inputStream.close(); //Close both streams. We don't need them any more.
outputStream.close();
}
„Das mit buffer verstehe ich ja, aber was hat es mit dieser count-Variable auf sich?“
„Wenn wir den letzten Datenblock aus einer Datei lesen, erhalten wir vielleicht z.B. 328 statt 1000 Bytes. Wenn wir also die Daten schreiben, müssen wir angeben, dass wir nicht den gesamten Block schreiben, sondern nur die ersten 328 Bytes.“
Wenn wir den letzten Block lesen, gibt die read-Methode die Anzahl der tatsächlich gelesenen Bytes zurück. 1000 jedes Mal, wenn wir einen Block lesen, mit Ausnahme des letzten Blocks, wo wir 328 erhalten.
Wenn wir also einen Block schreiben, geben wir an, dass nicht alle Bytes im Puffer geschrieben werden sollen, sondern nur 328 (d.h. der in der count-Variable gespeicherte Wert).
„Jetzt ist es mir klar. Danke, Ellie.“
GO TO FULL VERSION