использование java.util.Scanner для чтения файла побайтно - PullRequest
5 голосов
/ 11 января 2010

Я пытаюсь прочитать однострочный файл за символом, используя java.util.Scanner. Однако я получаю это исключение ":

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

Вот мой код:

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

У кого-нибудь есть идеи относительно того, что я могу делать неправильно?

Редактировать: я понял, что написал hasNext () вместо hasNextByte (). Однако, если я это сделаю, он ничего не распечатает.

Ответы [ 4 ]

10 голосов
/ 11 января 2010

С какой стати вы хотите использовать сканер для чтения файла побайтно? Это все равно, что использовать тачку для перевозки смены кармана. (Если вам действительно нужна тачка для смены кармана, дайте мне знать, чтобы я мог стать вашим другом).

А если серьезно: класс InputStream читает байты из файла просто и надежно и больше ничего не делает.

Класс scanner был недавно введен в API Java, поэтому примеры из учебников могут извлечь данные из файла с меньшими затратами, чем обычно при использовании каскада new BufferedReader(new InputStream). Его специальность - ввод чисел и строк из входных файлов произвольной формы. Метод nextByte() фактически читает одну или несколько десятичных цифр из входного потока (если они там есть) и преобразует таким образом сканированное число в одно байтовое значение.

А если вы читаете байты, почему вы хотите вывести их как char s? Байты являются , а не символами, и взаимное преобразование методом перебора в некоторых местах завершится неудачно. Если вы хотите увидеть значения этих байтов, выведите их как есть, и вы увидите маленькие целые числа от 0 до 255.

Если вы хотите прочитать char s из файла, FileReader - это класс для вас.

2 голосов
/ 11 января 2010

Сканер предназначен для анализа текстовых данных - его метод nextByte() предполагает, что ввод состоит из цифр (возможно, перед ними стоит знак).

Возможно, вы захотите использовать FileReader, если вы на самом деле читаете текстовые данные, или FileInputStream, если это двоичные данные. Или FileInputStream, заключенный в InputStreamReader, если вы читаете текст с определенной кодировкой символов (к сожалению, FileReader не позволяет вам указать кодировку, но неявно использует кодировку платформы по умолчанию, что часто не хорошо).

1 голос
/ 15 августа 2015

Scanner - это чтение текста с разделителями (см. документы ).

nextByte будет продолжать чтение до тех пор, пока не достигнет указанного вами разделителя (по умолчанию пробел), а затем попытается преобразовать эту строку в байт.

Таким образом, если в файле 123 456, один вызов nextByte вернет 123, а не 49 (десятичное значение для символа 1).


Если вы хотите читать побайтово, вы можете использовать FileInputStream.

1 голос
/ 11 января 2010

При устранении неполадок Scanner проверьте наличие ошибок ввода-вывода :

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

Хотя я с остальными - это, вероятно, не тот класс, который нужен для работы. Если вы хотите ввести байты, используйте InputStream (в этом случае FileInputStream). Если вы хотите ввести символ, используйте Reader (например, InputStreamReader).

...