2010-01-11 9 views
5

Ich versuche, eine einzeilige Datei Zeichen für Zeichen mit java.util.Scanner zu lesen. Ich bin diese Ausnahme jedoch "bekommen:mit java.util.Scanner, um eine Datei byteweise zu lesen

Exception in thread "main" java.util.InputMismatchException: For input string: "contents of my file" 
    at java.util.Scanner.nextByte(Scanner.java:1861) 
    at java.util.Scanner.nextByte(Scanner.java:1814) 
    at p008.main(p008.java:18) <-- line where I do scanner.nextByte() 

mein Code hier:

public static void main(String[] args) throws FileNotFoundException { 
    File source = new File("file.txt"); 
    Scanner scanner = new Scanner(source); 
    while(scanner.hasNext()) { 
     System.out.println((char)scanner.nextByte()); 
    } 
    scanner.close() 
} 

Hat jemand irgendwelche Ideen, was ich tun könnte falsch

Edit:? Ich wurde mir klar, schrieb hasNext() anstelle von hasNextByte(), aber wenn ich das tue, druckt es nichts aus

+6

Ein Scanner dient zum Parsen der Zeicheneingabe. Ich vermute, dass du einen InputStream brauchst. –

Antwort

10

Warum in aller Welt möchten Sie einen Scanner verwenden, um eine Datei byteweise zu lesen? Das ist wie mit einem Wheelb Pfeil zum Transport Ihres Taschengelds. (Wenn Sie wirklich eine Schubkarre für Ihren Taschenwechsel brauchen, lassen Sie es mich wissen, damit ich Ihr Freund werden kann).

Aber im Ernst: Klasse InputStream liest Bytes aus einer Datei, einfach und zuverlässig, und tut nichts anderes.

Die Klasse scanner wurde kürzlich in die Java-API eingeführt, sodass Lehrbuchbeispiele Daten aus einer Datei mit weniger Schmerzen extrahieren konnten als normalerweise bei der Verwendung der Kaskade new BufferedReader(new InputStream). Seine Spezialität ist die Eingabe von Zahlen und Zeichenfolgen aus Eingabedateien in freier Form. Die Methode nextByte() liest tatsächlich eine oder einige Dezimalziffern aus dem Eingabestream (falls vorhanden) und konvertiert die so gescannte Zahl in einen einzelnen Bytewert. Wenn Sie Bytes lesen, warum möchten Sie sie als char s ausgeben? Bytes sind nicht Zeichen, und Brute-Force-Interconverting wird an einigen Stellen fehlschlagen. Wenn Sie die Werte dieser Bytes sehen wollen, drucken sie aus, wie sie sind, und Sie werden kleine ganze Zahlen zwischen 0 und 255

sehen Wenn Sie char s aus einer Datei lesen wollen, FileReader die Klasse für Sie .

+0

Ich habe eine Textdatei, die mit dem Wort "Abstract" beginnt (was für eine Überraschung ...). Jedenfalls wenn ich versuche mit zu lesen: Scanner Scanner = neuer Scanner (Datei); Byte b = scanner.nextByte(); Ich erhalte java.util.InputMismatchException. Warum sehe ich keine Werte zwischen 0 und 255, können Sie mir bitte helfen? Die Datei ist UTF-8. –

+0

Meine Antwort erklärte das, aber vielleicht nicht sehr gut. Scanner liest und interpretiert Textformeingabe, keine Low-Level-Bytes! Versuchen Sie, eine Datei zu erstellen, deren erste Zeile '1 10 100 1000 hallo' lautet, und lesen Sie diese mit 'Scanner.nextByte()'. Sie werden die Zahlen 1, 10 und 100 erfolgreich als Bytes lesen und zurückgeben, leiden aber an einer Ausnahme bei 1000 und (wenn Sie darüber gelesen haben) an "Hallo", weil dies keine Werte sind, die in einem Byte dargestellt werden können. –

2

Scanner ist für Parsing Textdaten - seine nextByte() Methode erwartet die Eingabe aus Ziffern bestehen (möglicherweise mit einem Vorzeichen vorangestellt).

Sie möchten wahrscheinlich eine FileReader verwenden, wenn Sie tatsächlich Textdaten lesen, oder eine FileInputStream, wenn es sich um binäre Daten handelt. Oder ein FileInputStream in einem InputStreamReader eingewickelt, wenn Sie Text mit einer bestimmten Zeichenkodierung lesen (leider FileReader können Sie nicht die Codierung angeben, sondern verwendet die Plattform Standardcodierung implizit, die oft nicht gut ist).

+0

Sorry, was meinst du mit "Parsing von Textdaten" und "Lesen von Textdaten"? –

+0

@KorayTugay: Lesen bedeutet, einfach nehmen, was kommt, ein Byte (oder Zeichen) nach dem anderen. Parsen bedeutet, dass Sie erwarten, dass die Daten eine bestimmte Struktur oder ein bestimmtes Format haben, z. B. eine Zeichenfolge, die aus Ziffern besteht, denen ein optionales Minuszeichen vorangestellt ist, sodass Sie sie als Zahl interpretieren können. –

+0

Danke für den Kommentar. Also nextByte-Methode in der Scanner-Klasse ist nur zum "Lesen von Ziffern"? –

1

Wenn Scanner Fehlerbehebung prüfen underlying I/O errors:

if(scanner.ioException() != null) { 
    throw scanner.ioException(); 
} 

Obwohl ich mit den anderen bin - das ist wahrscheinlich nicht die richtige Klasse für den Job. Wenn Sie eine Byte-Eingabe wünschen, verwenden Sie eine (in diesem Fall FileInputStream). Wenn Sie eine char-Eingabe wünschen, verwenden Sie eine Reader (z. B. InputStreamReader).

1

Scanner ist alles über das Lesen von Text mit Trennzeichen (siehe the docs).

nextByte wird weiterlesen, bis es zu dem Trennzeichen kommt, das Sie angegeben haben (whitespace standardmäßig) und dann versuchen, diese Zeichenfolge in ein Byte zu konvertieren.

Also, wenn Sie 123 456 in einer Datei haben, ein Anruf zu nextByte wird 123 zurückkehren, nicht 49 (den Dezimalwert für die 1 Zeichen).


Wenn Sie Byte-für-Byte lesen möchten, können Sie FileInputStream verwenden.

Verwandte Themen