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

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

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

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

4 ответа

Решение

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам