Ваша проблема не в том, что вы выполняете свой код, а скорее в предположениях, которые вы должны сделать относительно путей к файлам, доступных внешних команд (если они вам нужны), необходимых прав доступа к файлам и других внешних факторов, которые на самом деле не подпадают под «Java» проблемный домен. Если вы не планируете использовать нативный код (через JNI), Java не будет вашей проблемой, ваша среда будет. Что возвращает нас к старой поговорке: «пиши один раз, тестируй везде».
Следующий метод решает проблему с использованием juniversalchardet , который является портом Java библиотеки обнаружения кодирования Mozilla.
public static String guessEncoding(byte[] bytes) {
String DEFAULT_ENCODING = "UTF-8";
org.mozilla.universalchardet.UniversalDetector detector =
new org.mozilla.universalchardet.UniversalDetector(null);
detector.handleData(bytes, 0, bytes.length);
detector.dataEnd();
String encoding = detector.getDetectedCharset();
detector.reset();
if (encoding == null) {
encoding = DEFAULT_ENCODING;
}
return encoding;
}
Приведенный выше код был протестирован и работает как задумано. Просто добавьте juniversalchardet-1.0.3.jar в путь к классам.
Я тестировал как juniversalchardet , так и jchardet . Мое общее впечатление таково, что juniversalchardet обеспечивает лучшую точность обнаружения и лучший API из двух библиотек.
Вот мой любимый: https://github.com/codehaus/guessencoding
Это работает так:
Это может показаться чересчур упрощенным, но в моей повседневной работе точность превышает 90%.
Ответ Чи кажется наиболее многообещающим для реального использования. Я просто хочу добавить, что, по словам Джоэла Спольски, в свое время Internet Explorer использовал алгоритм угадывания на основе частоты:
http://www.joelonsoftware.com/articles/Unicode.html
Грубо говоря, все предполагаемый текст копируется и анализируется во всех возможных кодировках. Выигрывает тот синтаксический анализ, который лучше всего соответствует среднему профилю частотности слов (и букв?) Языка. Я не могу быстро понять, использует ли jchardet такой же подход, поэтому я подумал, что упомяну об этом на всякий случай.
Без индикатора кодировки вы никогда не узнаете наверняка. Однако вы можете сделать несколько умных предположений. См. Мой ответ на этот вопрос:
Как определить, содержит ли строка недопустимые закодированные символы
Используйте методы validUTF8 (). Если он возвращает true, трактуйте его как UTF8, иначе как Latin-1.