Java: Как определить правильную кодировку кодировки потока - PullRequest
124 голосов
/ 31 января 2009

Применительно к следующей теме: Приложение Java: невозможно прочитать файл в кодировке iso-8859-1

Каков лучший способ программно определить правильную кодировку кодировки входного потока / файла?

Я пытался использовать следующее:

File in =  new File(args[0]);
InputStreamReader r = new InputStreamReader(new FileInputStream(in));
System.out.println(r.getEncoding());

Но для файла, который, как я знаю, закодирован с помощью ISO8859_1, приведенный выше код выдает ASCII, что неверно и не позволяет мне корректно отобразить содержимое файла обратно на консоль.

Ответы [ 15 ]

4 голосов
/ 31 января 2009

Если вы не знаете кодировку ваших данных, это не так легко определить, но вы можете попробовать использовать библиотеку , чтобы угадать ее . Также есть аналогичный вопрос .

2 голосов
/ 26 мая 2009

Для файлов ISO8859_1 нет простого способа отличить их от ASCII. Однако для файлов Unicode это обычно можно определить по первым нескольким байтам файла.

Файлы UTF-8 и UTF-16 содержат Порядок следования байтов (BOM) в самом начале файла. Спецификация - это неразрывное пространство нулевой ширины.

К сожалению, по историческим причинам Java не обнаруживает это автоматически. Такие программы, как «Блокнот», будут проверять спецификацию и использовать соответствующую кодировку. Используя unix или Cygwin, вы можете проверить спецификацию с помощью команды file. Например:

$ file sample2.sql 
sample2.sql: Unicode text, UTF-16, big-endian

Для Java я предлагаю вам проверить этот код, который будет определять общие форматы файлов и выбирать правильную кодировку: Как прочитать файл и автоматически указать правильную кодировку

1 голос
/ 11 мая 2015

Альтернативой TikaEncodingDetector является использование Tika AutoDetectReader .

Charset charset = new AutoDetectReader(new FileInputStream(file)).getCharset();
0 голосов
/ 28 июля 2018

В простой Java:

final String[] encodings = { "US-ASCII", "ISO-8859-1", "UTF-8", "UTF-16BE", "UTF-16LE", "UTF-16" };

List<String> lines;

for (String encoding : encodings) {
    try {
        lines = Files.readAllLines(path, Charset.forName(encoding));
        for (String line : lines) {
            // do something...
        }
        break;
    } catch (IOException ioe) {
        System.out.println(encoding + " failed, trying next.");
    }
}

Этот подход будет проверять кодировки одну за другой, пока одна из них не сработает или мы не исчерпаем их. (Кстати, мой список кодировок содержит только эти элементы, поскольку они являются реализациями кодировок, необходимыми для каждой платформы Java, https://docs.oracle.com/javase/9/docs/api/java/nio/charset/Charset.html)

0 голосов
/ 31 января 2009

Можете ли вы выбрать соответствующий набор символов в конструкторе :

new InputStreamReader(new FileInputStream(in), "ISO8859_1");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...