В java есть несколько методов, которые вы никогда не должны использовать. когда-либо.
new FileReader(File)
- один из них.
Каждый раз, когда у вас есть вещь, которая представляет байты, и как-то выпадают символы или строки, или наоборот? Никогда не используйте их, если в spe c указанного метода явно не указано, что он всегда использует предустановленную кодировку. Почти все такие методы используют «системную кодировку по умолчанию», что означает, что операция зависит от машины, на которой вы ее запускаете. Это сокращение от «это не удастся, и ваши тесты этого не поймут». Что вам не нужно.
Вот почему вы никогда не должны использовать эти вещи.
FileReader был исправлен (есть второй конструктор, который принимает кодировку), но это только с JDK11 . У вас уже есть красивый новый API, почему вы снова переключаетесь на изящный старый File API? Не делайте этого.
Все различные методы в Files, такие как Files.newBufferedReader
, предназначены для использования UTF-8, если вы не укажете (в этом случае Files более полезен, и в отличие от большинство других java основных библиотек). Таким образом:
try (BufferedReader br = Files.newBufferedReader(file)) {
что просто .. лучше .., чем ваша линия.
Теперь, вероятно, это все равно не сработает. Но это хорошо! Это также выйдет из строя на вашей машине разработчика. Скорее всего, файл, который вы читаете, на самом деле не в UTF_8. Это вероятное предположение; большинство linuxen развертывается с кодировкой по умолчанию UTF_8, а большинство машин разработки - нет; если ваша машина разработчика работает, а ваша среда развертывания - нет, очевидный вывод состоит в том, что ваш входной файл не UTF_8. Это не обязательно должно быть то, что на вашем компьютере разработчика установлено по умолчанию; что-то вроде ISO_8859_1 никогда не будет генерировать исключения, но вместо этого будет читать gobbledygook. Ваш код может показаться работающим (без сбоев), но текст, который вы читаете, по-прежнему неверен.
Выясните, какая у вас кодировка текста, а затем укажите ее. Если это ISO_8859_1, например:
try (BufferedReader br = Files.newBufferedReader(file, StandardCharsets.ISO_8859_1)) {
, и теперь ваш код больше не имеет типа «работает на одних машинах, но не на других».
Проверьте строку, в которой произошел сбой, в шестнадцатеричный редактор, если нужно. Готов поспорить, доллары на пончики, там будет байт 0x80 или больше (в десятичном формате 128 или больше). Все, вплоть до 127, имеет тенденцию означать одно и то же в самых разных кодировках текста, от ASCII до любого варианта ISO-8859, до UTF-8 Windows Cp1252, до макромана и многих других вещей, при условии, что это все только простые буквы и цифры, неправильная кодировка не имеет никакого значения. Но как только вы дойдете до 0x80 или выше, все они станут другими. Вооруженный этим байтом + некоторое знание того, каким символом он должен быть, обычно является хорошим началом для выяснения, в какой кодировке находится этот текстовый файл.
NB: Если это не так, проверьте, как текст файл копируется с вашего компьютера разработчика в среду развертывания. Вы уверены, что это тот же файл? Если он копируется с помощью текстового механизма, снова может быть виновата кодировка кодировки, но на этот раз в том, как файл записан, а не в том, как ваше java приложение его читает.