Вопрос-ответ

Java : How to determine the correct charset encoding of a stream

Java : как определить правильную кодировку кодировки потока

Со ссылкой на следующий поток: Приложение 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, что неверно и не позволяет мне корректно отобразить содержимое файла обратно на консоль.

Переведено автоматически
Ответ 1

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

Метод GetEncoding() вернет кодировку, которая была настроена (прочитайте JavaDoc) для потока. Он не угадает кодировку за вас.

Некоторые потоки сообщают вам, какая кодировка использовалась для их создания: XML, HTML. Но не поток произвольных байтов.

В любом случае, вы могли бы попытаться угадать кодировку самостоятельно, если потребуется. Каждый язык имеет общую частоту для каждого символа. В английском символ e появляется очень часто, но, к сожалению,, будет появляться очень редко. В потоке ISO-8859-1 обычно нет символов 0x00. Но в потоке UTF-16 их много.

Или: вы могли бы спросить пользователя. Я уже видел приложения, которые представляют вам фрагмент файла в разных кодировках и просят вас выбрать "правильную".

Ответ 2

Я использовал эту библиотеку, аналогичную jchardet, для определения кодировки в Java: https://github.com/albfernandez/juniversalchardet

Ответ 3

проверьте это: http://site.icu-project.org / (icu4j) у них есть библиотеки для определения кодировки из IOStream, это может быть просто, например, так:

BufferedInputStream bis = new BufferedInputStream(input);
CharsetDetector cd = new CharsetDetector();
cd.setText(bis);
CharsetMatch cm = cd.detect();

if (cm != null) {
reader = cm.getReader();
charset = cm.getName();
}else {
throw new UnsupportedCharsetException()
}
Ответ 4

Вот мои любимые:

TikaEncodingDetector

Зависимость:

<dependency>
<groupId>org.apache.any23</groupId>
<artifactId>apache-any23-encoding</artifactId>
<version>1.1</version>
</dependency>

Пример:

public static Charset guessCharset(InputStream is) throws IOException {
return Charset.forName(new TikaEncodingDetector().guessEncoding(is));
}

GuessEncoding

Зависимость:

<dependency>
<groupId>org.codehaus.guessencoding</groupId>
<artifactId>guessencoding</artifactId>
<version>1.4</version>
<type>jar</type>
</dependency>

Пример:

  public static Charset guessCharset2(File file) throws IOException {
return CharsetToolkit.guessEncoding(file, 4096, StandardCharsets.UTF_8);
}
java file