Daten einlesen (Java): Unterschied zwischen den Versionen
K (→Einlesen mit {{JAPI|BufferedReader}}) |
K |
||
(Eine dazwischenliegende Version desselben Benutzers wird nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
− | Um mit Java Daten einzulesen hat man mehrere Möglichkeiten von Bytestreams und Characterstreams. | + | Um mit Java Daten einzulesen, hat man mehrere Möglichkeiten von Bytestreams und Characterstreams. |
Bytestreams eignen sich für alle Arten von Daten da alles als Binärdaten vorliegt, Characterstreams eignen sich besonders zum Einlesen und Schreiben von Zeichenketten im ASCII oder anderen Formaten. | Bytestreams eignen sich für alle Arten von Daten da alles als Binärdaten vorliegt, Characterstreams eignen sich besonders zum Einlesen und Schreiben von Zeichenketten im ASCII oder anderen Formaten. | ||
− | [[Klasse]] die für das Einlesen von Daten zuständig sind haben | + | [[Klasse|Klassen]], die für das Einlesen von Daten zuständig sind, haben jeweils ein ''Input'', bei Binärstreams oder ''Reader'', bei Charachterstreams im Namen. |
=Binär Streams= | =Binär Streams= | ||
Um Binärdaten einzulesen können alle Streams verwendet werden die vom {{JAPI|InputStream}} abgeleitet sind, so z.B. der {{JAPI|FileInputStream}} oder auch der {{JAPI|BufferedInputStream}}. | Um Binärdaten einzulesen können alle Streams verwendet werden die vom {{JAPI|InputStream}} abgeleitet sind, so z.B. der {{JAPI|FileInputStream}} oder auch der {{JAPI|BufferedInputStream}}. | ||
− | Der FileInputStream ist der einzigste Bytestream der direkt auf Dateien zugreifen kann | + | Der FileInputStream ist der einzigste Bytestream der direkt auf Dateien zugreifen kann, daher wird er verwendet, wenn man Daten aus eine [[Datei]] einlesen will. |
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
FileInputStream fin = new FileInputStream("datei"); | FileInputStream fin = new FileInputStream("datei"); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Hat man keine Datei sondern bekommt einen Stream, z.B. von einem {{JAPI|Socket}} kann man für diese ein InputStream [[Objekt]] deklarieren. | + | Hat man keine Datei sondern bekommt einen Stream, z.B. von einem {{JAPI|Socket}} kann man für diese ein InputStream-[[Objekt]] deklarieren. |
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
InputStream in = socket.getInputStream(); | InputStream in = socket.getInputStream(); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Wenn man den Stream hat kann man dann die Daten aus dem Stream mit den verschiedenen read()-Methoden laden, jedoch kapselt man die einfachen Streams oftmals noch in einem gepufferten Stream, BufferedInputStream um so die Lesezugriffe auf das Medium zu minimieren. | + | Wenn man den Stream hat, kann man dann die Daten aus dem Stream mit den verschiedenen read()-Methoden laden, jedoch kapselt man die einfachen Streams oftmals noch in einem gepufferten Stream, BufferedInputStream um so die Lesezugriffe auf das Medium zu minimieren. |
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
BufferedInputStream bufin = new BufferedInputStream(in); | BufferedInputStream bufin = new BufferedInputStream(in); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | Nach dem Öffnen des Streams fängt man immer am 1. Byte des Streams an, man kann sich das wie ein [[Zeiger]] vorstellen der nach jedem Lesevorgang um die gelesenen Bytes vorbewegt. Die einfache read()-[[Methode]] ohne Parameter liest immer nur ein Byte und gibt dieses zurück. Desweiteren gibt es eine read()-Methode die ein byte [[Array]] als [[Argument]] bekommt, | + | Nach dem Öffnen des Streams fängt man immer am 1. Byte des Streams an, man kann sich das wie ein [[Zeiger]] vorstellen der nach jedem Lesevorgang um die gelesenen Bytes vorbewegt. Die einfache read()-[[Methode]] ohne Parameter liest immer nur ein Byte und gibt dieses zurück. Desweiteren gibt es eine read()-Methode die ein byte-[[Array]] als [[Argument]] bekommt, dieses Array muss vorher angelegt werden und wird dann komplett mit Daten gefüllt und die Anzahl der gelesenen Bytes wird als [[int]]-Wert zurückgegeben. So erfährt man, ob der Array komplett voll ist, oder ob er nur teilweise gefüllt wurde. Als dritte Methode gibt es die Methode mit drei Parametern einem byte-Array und zwei int-Werten, der byte-Array wird wie bei der anderen Methode mit Werten gefüllt und die beiden int-Werte beschreiben den Offset (Anzahl der Bytes die nicht gelesen werden) und die maximale Anzahl an Bytes die gelesen werden. Wie auch bei der anderen Methode wird die tatsächliche Anzahl an gelesenen Elementen zurückgegeben. |
Alle drei Methoden haben gemeinsam, dass wenn sie am Ende des Streams angelangt sind, -1 zurückgeben. | Alle drei Methoden haben gemeinsam, dass wenn sie am Ende des Streams angelangt sind, -1 zurückgeben. | ||
Einlesen einer ganzen Datei: | Einlesen einer ganzen Datei: | ||
Zeile 50: | Zeile 50: | ||
=Character Streams= | =Character Streams= | ||
− | Um Zeichenketten einzulesen nimmt man meistens Klassen die von {{JAPI|Reader}} abgeleitet sind, so z.B. {{JAPI|FileReader}} oder {{JAPI|BufferedReader}}. Diese Klassen bieten meistens auch die Möglichkeit die Daten in einen bestimmten [[Zeichensatz]] zu konvertieren. | + | Um Zeichenketten einzulesen, nimmt man meistens Klassen die von {{JAPI|Reader}} abgeleitet sind, so z.B. {{JAPI|FileReader}} oder {{JAPI|BufferedReader}}. Diese Klassen bieten meistens auch die Möglichkeit die Daten in einen bestimmten [[Zeichensatz]] zu konvertieren. |
Wie bei den Binärstreams gibt es auch hier nur einen Stream der nur direkt auf Dateien geht, der FileReader. | Wie bei den Binärstreams gibt es auch hier nur einen Stream der nur direkt auf Dateien geht, der FileReader. | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
Zeile 106: | Zeile 106: | ||
===Einlesen mit {{JAPI|BufferedReader}}=== | ===Einlesen mit {{JAPI|BufferedReader}}=== | ||
− | Die [[Klasse]] BufferedReader ist seit Java 1.1 mit im JDK. Sie verarbeitet | + | Die [[Klasse]] BufferedReader ist seit Java 1.1 mit im JDK. Sie verarbeitet Daten aus einem Zeicheneingabe-Datenstrom. |
Dem gepufferten Reader wird ein Inputstream übergeben, welchem wiederum die Datenquelle übergeben wird, aus der die Daten gelesen werden sollen. Hier also die Tastatur. | Dem gepufferten Reader wird ein Inputstream übergeben, welchem wiederum die Datenquelle übergeben wird, aus der die Daten gelesen werden sollen. Hier also die Tastatur. |
Aktuelle Version vom 18. November 2021, 15:36 Uhr
Um mit Java Daten einzulesen, hat man mehrere Möglichkeiten von Bytestreams und Characterstreams. Bytestreams eignen sich für alle Arten von Daten da alles als Binärdaten vorliegt, Characterstreams eignen sich besonders zum Einlesen und Schreiben von Zeichenketten im ASCII oder anderen Formaten.
Klassen, die für das Einlesen von Daten zuständig sind, haben jeweils ein Input, bei Binärstreams oder Reader, bei Charachterstreams im Namen.
Inhaltsverzeichnis
Binär Streams
Um Binärdaten einzulesen können alle Streams verwendet werden die vom InputStream
abgeleitet sind, so z.B. der FileInputStream
oder auch der BufferedInputStream
.
Der FileInputStream ist der einzigste Bytestream der direkt auf Dateien zugreifen kann, daher wird er verwendet, wenn man Daten aus eine Datei einlesen will.
FileInputStream fin = new FileInputStream("datei");
Hat man keine Datei sondern bekommt einen Stream, z.B. von einem Socket
kann man für diese ein InputStream-Objekt deklarieren.
InputStream in = socket.getInputStream();
Wenn man den Stream hat, kann man dann die Daten aus dem Stream mit den verschiedenen read()-Methoden laden, jedoch kapselt man die einfachen Streams oftmals noch in einem gepufferten Stream, BufferedInputStream um so die Lesezugriffe auf das Medium zu minimieren.
BufferedInputStream bufin = new BufferedInputStream(in);
Nach dem Öffnen des Streams fängt man immer am 1. Byte des Streams an, man kann sich das wie ein Zeiger vorstellen der nach jedem Lesevorgang um die gelesenen Bytes vorbewegt. Die einfache read()-Methode ohne Parameter liest immer nur ein Byte und gibt dieses zurück. Desweiteren gibt es eine read()-Methode die ein byte-Array als Argument bekommt, dieses Array muss vorher angelegt werden und wird dann komplett mit Daten gefüllt und die Anzahl der gelesenen Bytes wird als int-Wert zurückgegeben. So erfährt man, ob der Array komplett voll ist, oder ob er nur teilweise gefüllt wurde. Als dritte Methode gibt es die Methode mit drei Parametern einem byte-Array und zwei int-Werten, der byte-Array wird wie bei der anderen Methode mit Werten gefüllt und die beiden int-Werte beschreiben den Offset (Anzahl der Bytes die nicht gelesen werden) und die maximale Anzahl an Bytes die gelesen werden. Wie auch bei der anderen Methode wird die tatsächliche Anzahl an gelesenen Elementen zurückgegeben. Alle drei Methoden haben gemeinsam, dass wenn sie am Ende des Streams angelangt sind, -1 zurückgeben. Einlesen einer ganzen Datei: 1. nur ein Byte einlesen
int length;
while((length=bufin.read())!=-1)
{
System.out.println(length);
}
2. immer 250 Byte einlesen
int length;
byte[] buffer = new byte[250];
while((length=bufin.read(buffer))!=-1)
{
for(int i=0;i!=length;i++)
System.out.print(buffer[i]);
System.out.println();
}
3. nur ab dem 250.Byte 4 Byte einlesen
int length;
byte[] buffer = new byte[250];
length=bufin.read(buffer,250,4);
for(int i=0;i!=length;i++)
System.out.print(buffer[i]);
Character Streams
Um Zeichenketten einzulesen, nimmt man meistens Klassen die von Reader
abgeleitet sind, so z.B. FileReader
oder BufferedReader
. Diese Klassen bieten meistens auch die Möglichkeit die Daten in einen bestimmten Zeichensatz zu konvertieren.
Wie bei den Binärstreams gibt es auch hier nur einen Stream der nur direkt auf Dateien geht, der FileReader.
FileReader fin = new FileReader("Datei");
Hat man jedoch nur einen normalen Bytestream und will aber einen Reader verwenden, muss man den vorher Kapselung, dies kann man mit dem InputStreamReader
machen.
InputStreamReader in = new InputStreamReader(socket.getInputStream());
Wenn man den Reader hat kann man dann die Zeichen aus dem Stream mit den verschiedenen read()-Methoden laden, jedoch kapselt man die einfachen Streams oftmals noch in einem gepufferten Stream (BufferedReader) um so die Lesezugriffe auf das Medium zu minimieren und auch kompfortabler zu lesen. Denn der BufferedReader besitzt eine readLine()-Methode, welche eine komplette Zeile einliest, die man dann verarbeiten kann.
BufferedReader read = new BufferedReader(in);
Nach dem Öffnen des Readers fängt man immer am 1. Zeichen des Streams an, man kann sich das wie einen Zeiger vorstellen, der nach jedem Lesevorgang um die gelesenen Zeichen vorbewegt. Die einfache read()-Methode ohne Parameter liest immer nur ein Zeichen und gibt dieses zurück. Desweiteren gibt es eine read()-Methode, die ein char-Array als Argument bekommt. Dieser Array muss vorher angelegt werden und wird dann komplett mit Zeichen gefüllt, und die Anzahl der gelesenen Zeichen wird als int-Wert zurückgegeben. So erfährt man, ob der Array komplett voll ist oder ob er nur teilweise gefüllt wurde. Als dritte Methode gibt es die Methode mit drei Parametern einem char-Array und zwei int-Werten. Der char-Array wird wie bei der anderen Methode mit Werten gefüllt und die beiden int-Werte beschreiben den Offset (Anzahl der Zeichen die nicht gelesen werden) und die maximale Anzahl an Zeichen die gelesen werden. Wie auch bei der anderen Methode wird die tatsächliche Anzahl an gelesenen Elementen zurückgegeben.
Alle drei Methoden haben gemeinsam, dass wenn sie am Ende des Streams angelangt sind, -1 zurückgeben. Die letzte Methode ist die readLine()-Methode des BufferedReader, diese liest immer eine ganze Zeile ein bis zum \n oder \r oder \r\n und gibt den String
ohne den Zeilenumbruch zurück. Ist sie am Ende der Datei angelangt, gibt sie null zurück.
Einlesen einer ganzen Datei:
1. nur ein Zeichen einlesen
int length;
while((length=read.read())!=-1)
{
System.out.println((char)length);
}
2. immer 250 Zeichen einlesen
int length;
char[] buffer = new char[250];
while((length=read.read(buffer))!=-1)
{
for(int i=0;i!=length;i++)
System.out.print(buffer[i]);
System.out.println();
}
3. nur ab dem 250.Zeichen 4 Zeichen einlesen
int length;
char[] buffer = new char[250];
length=read.read(buffer,250,4);
for(int i=0;i!=length;i++)
System.out.print(buffer[i]);
4. immer eine Zeile einlesen
String line;
while((line=read.readLine())!=null)
System.out.println(line);
Zeichen von der Konsole einlesen
Im vorigen Kapitel haben wir das Einlesen von Zeichenketten (Strings) aus Streams gesehen, die auf Dateien zeigen. Nun wollen wir uns noch ansehen, wie man Tastatureingaben von der Konsole einliest/entgegennimmt.
Es gibt zwei praktikable Varianten, die sich hinsichtlich ihrer Möglichkeiten unterschieden.
Einlesen mit BufferedReader
Die Klasse BufferedReader ist seit Java 1.1 mit im JDK. Sie verarbeitet Daten aus einem Zeicheneingabe-Datenstrom.
Dem gepufferten Reader wird ein Inputstream übergeben, welchem wiederum die Datenquelle übergeben wird, aus der die Daten gelesen werden sollen. Hier also die Tastatur.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Der Reader stellt nun Methoden bereit, um aus dem InputStream zu lesen. Wir geben beim Lesen von der Eingabezeile der readLine()-Methode den Vorzug.
System.out.print("Gib deinen Namen ein: ");
String line = reader.readLine(); //auslesen der Tastatureingabe
Einlesen mit Scanner
Seit Java 5 ist nun auch die recht komfortable Klasse Scanner mit im JDK.
Die Codezeile für das Lesen mit einem Scanner-Objekt sieht ziemlich ähnlich aus:
Scanner reader = new Scanner(System.in));
Zum Einlesen beliebiger Zeichenketten von der Tastatur kann die next()
-Methode eingesetzt werden:
System.out.print("Gib deinen Namen ein: ");
String line = reader.next(); //auslesen der Tastatureingabe
Scanner kennt noch viele weitere spezialisierte Methoden zum Einlesen, die an bestimmte primitive Datentypen angepasst sind.
Ein Beispiel für eine Fließkommazahl mit doppelter Genauigkeit (double):
System.out.print("Gib eine Dezimalzahl ein: ");
double line = reader.nextDouble(); //auslesen der Tastatureingabe