@ VGR понял все правильно.
tl; dr: Use Scanner in = new Scanner(new File(fileName), "ISO-8859-1");
Похоже, что происходит:
- Ваш файл не являетсядопустимый UTF-8 из-за этого одиночного символа 0x9C.
- Сканер считывает файл как UTF-8, поскольку это системное значение по умолчанию
- Базовые библиотеки выдают
MalformedInputException
- Сканер ловит и скрывает его (многозначное, но ошибочное дизайнерское решение)
- Он начинает сообщать, что у него больше нет строк
- Вы не узнаете, что все пошло не так, если вы на самом делеспросите сканер
Вот MCVE:
import java.io.*;
import java.util.*;
class Test {
public static void main(String[] args) throws Exception {
Scanner in = new Scanner(new File(args[0]), args[1]);
while (in.hasNextLine()) {
String line = in.nextLine();
System.out.println("Line: " + line);
}
System.out.println("Exception if any: " + in.ioException());
}
}
Вот пример обычного вызова:
$ printf 'Hello\nWorld\n' > myfile && java Test myfile UTF-8
Line: Hello
Line: World
Exception if any: null
Вот что вы видите (кромечто вы не получите и покажете скрытое исключение).Обратите внимание, в частности, на то, что строки не отображаются:
$ printf 'Hello\nWorld \234\n' > myfile && java Test myfile UTF-8
Exception if any: java.nio.charset.MalformedInputException: Input length = 1
И здесь, когда декодируется как ISO-8859-1, декодирование, в котором все последовательности байтов действительны (даже если 0x9C не имеет назначенного символа и поэтомуне отображается в терминале):
$ printf 'Hello\nWorld \234\n' > myfile && java Test myfile ISO-8859-1
Line: Hello
Line: World
Exception if any: null
Если вас интересуют только данные ASCII и у вас нет строк UTF-8, вы можете просто попросить сканер использовать ISO-8859-1
передав его в качестве второго параметра конструктору Scanner
:
Scanner in = new Scanner(new File(fileName), "ISO-8859-1");