Чтение файла с помощью Java-сканера

Одна из строк в java-файле, которую я пытаюсь понять, приведена ниже.

return new Scanner(file).useDelimiter("\\Z").next();

Ожидается, что файл вернется до «конца ввода, но для конечного терминатора, если он есть» в соответствии с документацией java.util.regex.Pattern. Но что происходит, он возвращает только первые 1024 символа из файла. Является ли это ограничением, налагаемым сопоставлением шаблонов регулярных выражений? Можно ли это преодолеть? В настоящее время я собираюсь использовать программу для чтения файлов. Но хотелось бы знать причину такого поведения.


person Sharmila    schedule 04.10.2010    source источник
comment
НИКОГДА не используйте сканер! На самом деле, вы получите столько неприятностей.   -  person Martijn Courteaux    schedule 04.10.2010
comment
@Martijn Courteaux - постарайтесь дать хоть малейший намек на то, почему Scanner плохой?   -  person whaley    schedule 06.10.2010


Ответы (4)


Попробуйте обернуть объект file в FileInputStream

person Amir Afghani    schedule 04.10.2010
comment
Не могли бы вы отредактировать свой ответ, чтобы объяснить, почему это поможет и в чем основная проблема? В нынешнем виде это не более чем комментарий. - person Fund Monica's Lawsuit; 06.02.2017

Сам я не смог воспроизвести это. Но я думаю, что могу пролить свет на то, что происходит.

Внутри Сканер использует символьный буфер из 1024 символов. Сканер по умолчанию будет считывать 1024 символа, доступные для чтения, если это возможно, а затем применит шаблон.

Проблема в вашем шаблоне... он всегда будет соответствовать концу ввода, но это не означает конец вашего входного потока/данных. Когда Java применяет ваш шаблон к буферизованным данным, она пытается найти первое вхождение конца ввода. Поскольку в буфере находится 1024 символа, механизм сопоставления называет позицию 1024 первым совпадением разделителя и все, что до него, возвращается в качестве первого токена.

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

person Mark Peters    schedule 04.10.2010
comment
Привет, Марк, я думаю, что это правильная причина, по которой сканер не работает. Я голосую за ответ. Способ заставить его работать - тот, который помечен как правильный. Спасибо за ваш ответ. - person Sharmila; 04.10.2010

Scanner предназначен для чтения нескольких примитивов из файла. Он действительно не предназначен для чтения всего файла.

Если вы не хотите включать сторонние библиотеки, вам лучше зациклиться на BufferedReader, который оборачивает FileReader/InputStreamReader для текста, или зациклиться на FileInputStream для двоичных данных.

Если вы согласны использовать стороннюю библиотеку, Apache commons-io имеет FileUtils, содержащий статические методы readFileToString и readLines для текста и readFileToByteArray для двоичных данных..

person Powerlord    schedule 04.10.2010

Вы можете использовать класс Scanner, просто укажите набор символов при открытии сканера, т.е.:

Scanner sc = new Scanner(file, "ISO-8859-1");

Java преобразует байты, считанные из файла, в символы, используя указанную кодировку, которая является кодировкой по умолчанию (из базовой ОС), если ничего не указано (источник). Мне до сих пор непонятно, почему Scanner считывает только 1024 байта с дефолтным, а с другим доходит до конца файла. Во всяком случае, работает нормально!

person Davide Aliprandi    schedule 02.05.2013