Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 474
openidsucks Avatar asked Jan 11 '10 00:01

openidsucks


3 Answers

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 chars? 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 chars from a file, FileReader is the class for you.

like image 73
Carl Smotricz Avatar answered Sep 17 '22 11:09

Carl Smotricz


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

like image 36
Michael Borgwardt Avatar answered Sep 20 '22 11:09

Michael Borgwardt


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 (e.g. InputStreamReader).

like image 23
McDowell Avatar answered Sep 19 '22 11:09

McDowell