简体   繁体   中英

using java.util.Scanner to read a file byte by byte

I'm trying to read a one line file character by character using java.util.Scanner. However I'm getting this exception":

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()

Here's my code:

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()
}

Does anyone have any ideas as to what I might be doing wrong?

Edit: I realized I wrote hasNext() instead of hasNextByte(). However if I do that it doesn't print out anything.

Why on earth would you want to use a scanner to read a file byte by byte? That's like using a wheelbarrow to transport your pocket change. (If you really need a wheelbarrow for your pocket change, let me know so I can become your friend).

But seriously: Class InputStream reads bytes from a file, simply and reliably, and does nothing else.

Class scanner was recently introduced into the Java API so textbook examples could pull data out of a file with less pain than is usually involved with using the cascade of new BufferedReader(new InputStream) . Its specialty is inputting numbers and strings from free-form input files. The nextByte() method actually reads one or a few decimal digits from the input stream (if they're there) and converts the number thus scanned into a single byte value.

And if you're reading bytes, why do you want to output them as char s? Bytes are not chars, and brute-force interconverting will fail in some places. If you want to see the values of those bytes, print them out as they are and you'll see small integers between 0 and 255.

If you want to read char s from a file, FileReader is the class for you.

Scanner is for parsing text data - its nextByte() method expects the input to consist of digits (possibly preceded by a sign).

You probably want to use a FileReader if you're actually reading text data, or a FileInputStream if it's binary data. Or a FileInputStream wrapped in an InputStreamReader if you're reading text with a specific character encoding (unfortunately, FileReader does not allow you to specify the encoding but uses the platform default encoding implicitly, which is often not good).

When troubleshooting Scanner , check for underlying I/O errors :

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

Though I'm with the others - this probably isn't the right class for the job. If you want byte input, use an InputStream (in this case, FileInputStream ). If you want char input, use a Reader (eg InputStreamReader ).

Scanner is all about reading delimited text (see the docs ).

nextByte will keep reading until it gets to whichever delimiter you specified (whitespace by default) and then try to convert that string into a byte.

So if you have 123 456 in a file, one call to nextByte will return 123 , not 49 (the decimal value for the 1 character).


If you want to read byte-by-byte, you could use FileInputStream .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM