Java как определить кодировку файла
Перейти к содержимому

Java как определить кодировку файла

  • автор:

Русские Блоги

Как получить кодировку символов текстового файла в Java [версия UTF-8, улучшенная версия]

1. Распознать кодировку символов:

1. Кодировка String в Java по умолчанию — UTF-8, которую можно получить с помощью следующего оператора: Charset.defaultCharset();

2. По умолчанию в Windows используется кодировка текстовых файлов ANSI, для китайских операционных систем — GBK. Например, если мы используем программу «Блокнот» для создания нового текстового документа, кодировка символов по умолчанию — ANSI.

3. Для текстовых текстовых документов предусмотрены четыре варианта кодирования: ANSI, Unicode (включая Unicode Big Endian и Unicode Little Endian), UTF-8, UTF-16.

4. Поэтому, когда мы читаем txt-файл, мы иногда можем не знать его формат кодирования, поэтому нам нужно использовать программу для динамического определения кодировки txt-файла.

  • ANSI: нет определения формата, GBK или GB2312 для китайских операционных систем
  • UTF-8: первые три байта: 0xE59B9E (UTF-8), 0xEFBBBF (UTF-8 с спецификацией)
  • UTF-16: первые два байта: 0xFEFF
  • Unicode: первые два байта: 0xFFFE

Например, если документ Unicode начинается с 0xFFFE, используйте программу, чтобы вынуть первые несколько байтов и оценить.

5. Соответствие между кодировкой Java и кодировкой текста:

UTF-8 содержит две спецификации:

Нужно судить о первых трех байтах:

Первые три байта: 0xE59B9E

Первые три байта: 0xEFBBBF

Юникод содержит две спецификации:

1、UCS2 Little Endian

2、UCS2 Big Endian

Java читает текстовый файл. Если формат кодирования не совпадает, появятся искаженные символы. Поэтому вам необходимо установить правильную кодировку символов при чтении текстовых файлов. Формат кодирования текстового документа записывается в заголовке файла. Формат кодирования файла необходимо проанализировать в программе. После получения формата кодирования файл не будет искажен при чтении файла в этом формате.

Java как определить кодировку файла

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

public class Encodings
public static void main(String[] args) throws IOException
FileInputStream inputStream = new FileInputStream(«d:/data.txt»);
FileOutputStream outputStream = new FileOutputStream(«d:/data.txt»);
SortedMap<String, Charset> charsets = Charset.availableCharsets();//список доступных кодировок
Charset currentCharset = Charset.defaultCharset();//узнать текущую кодировку
String s = «Good news everyone!»;
byte[] buffer = s.getBytes(«Windows-1251»);//создать массив байт в любой известной Java кодировке
byte[] fileBuffer = new byte[1000];
inputStream.read(fileBuffer);
String s1 = new String(fileBuffer, «Windows-1251»);//преобразовать набор байт, прочитанных из файла в строку
//преобразовать набор байт из одной кодировки в другую
Charset koi8 = Charset.forName(«KOI8-R»);
Charset windows1251 = Charset.forName(«Windows-1251»);
byte[] buffer3 = new byte[1000];
inputStream.read(buffer3);
String s3 = new String(buffer3, koi8);
buffer3 = s3.getBytes(windows1251);
outputStream.write(buffer3);
>
>

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Как узнать кодировку текстового файла

Есть программа которая обрабатывает текстовый файл. Нужно перед открытием и работой с файлом чтобы программа проверила кодировку текста. Подскажите как это реализовать, я только начинаю осваивать Java, буду признателен за пример кода.

TСPakko's user avatar

Вообще это непростая задача и я думаю не всегда возможно это сделать. Обычно кодировку определяют заранее. Но действительно (как и сказал @metalurgus) довольно много информации в сети. Хотя, нужно понимать, что для решения такой задачи понадобится использовать какую-нибудь стороннюю библиотеку думаю вот это рассуждение подходит: определение кодировки

Коллеги уже писали, что единого рецепта как бы нет, но я таки попытаюсь описать примерный паттерн решения этой задачи:

1) Получаем список поддерживаемых данной платформой кодировок Charset.availableCharset()

2) Берем первую по списку charset и читаем строчку из файла:

3) Берем Yandex Словарь и оформляем JSon запрос lookup, запоминаем статистику переводов

4) После прогона всех доступных кодировок выбираем ту, которая получила наилучшую статистику — это и будет наша искомая кодировка.

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

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

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

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

14 ответов

Я использовал эту библиотеку, подобную jchardet для обнаружения кодировки в Java: http://code.google.com/p/juniversalchardet/

mgk25/ucs/examples/UTF-8-test.txt ", но получил нулевое значение в качестве обнаруженного набора символов. UniversalDetector ud = новый UniversalDetector (null); byte [] bytes = FileUtils.readFileToByteArray (новый файл (файл)); ud.handleData (bytes, 0, bytes.length); ud.dataEnd (); обнаруженоCharset = ud.getDetectedCharset ();

Вы не можете определить кодировку произвольного байтового потока. Это характер кодировок. Кодировка означает сопоставление между байтом и его представлением. Поэтому каждая кодировка «может» быть правильной.

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

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

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

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

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

Вот мои фавориты:

Вы можете, конечно, проверить файл для определенной кодировки декодировать его с помощью CharsetDecoder и следить за ошибками «неправильный ввод» или «неуправляемый символ». Конечно, это говорит только о неправильной кодировке; он не говорит вам, правильно ли это. Для этого вам нужна основа для сравнения для оценки декодированных результатов, например. знаете ли вы заранее, если символы ограничены каким-то подмножеством, или текст придерживается какого-то строгого формата? Суть в том, что обнаружение набора символов — это догадки без каких-либо гарантий.

Вышеупомянутые библиотеки — это простые детекторы спецификации, которые, конечно, работают только в том случае, если в начале файла есть спецификация. Взгляните на http://jchardet.sourceforge.net/, который сканирует текст

Я нашел хорошую стороннюю библиотеку, которая может обнаруживать фактическую кодировку: http://glaforge.free.fr/wiki/index.php?wiki=GuessEncoding

Я не тестировал его широко, но, похоже, он работает.

Не забудьте поставить все, чтобы попытаться поймать его.

Я надеюсь, что это сработает для вас.

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

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

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

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

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

Ive написал мета-инструмент Java для обнаружения кодировки кодировки веб-страниц HTML, используя IBM ICU4j и Mozilla JCharDet в качестве встроенных компонентов. Здесь вы можете найти мой инструмент, пожалуйста, прочитайте раздел README перед чем-либо еще. Кроме того, вы можете найти некоторые основные понятия этой проблемы в моей статье и в ее ссылках.

Ниже я представил некоторые полезные комментарии, которые я испытал в своей работе:

  • Обнаружение кодировки не является надежным процессом, потому что оно основано на статистических данных, и на самом деле происходит угадать не обнаружение
  • icu4j является основным инструментом в этом контексте IBM, imho
  • Оба TikaEncodingDetector и Lucene-ICU4j используют icu4j, и их точность не имела существенного отличия от того, что icu4j в моих тестах (самое большее% 1, насколько я помню)
  • icu4j гораздо более общий, чем jchardet, icu4j просто немного предвзято относится к кодировкам семейства IBM, в то время как jchardet сильно привязан к utf-8
  • Из-за широкого использования UTF-8 в HTML-мире; jchardet — лучший выбор, чем icu4j в целом, но это не лучший выбор!
  • icu4j отлично подходит для восточно-азиатских специфических кодировок, таких как EUC-KR, EUC-JP, SHIFT_JIS, BIG5 и кодировки семейства GB
  • Оба icu4j и jchardet являются ошибками при работе с HTML-страницами с кодировками Windows-1251 и Windows-1256. Windows-1251 aka cp1251 широко используется для кириллических языков, таких как русский и Windows-1256, ака cp1256 широко используется для арабского языка.
  • Практически все средства обнаружения кодирования используют статистические методы, поэтому точность вывода сильно зависит от размера и содержимого ввода
  • Некоторые кодировки по существу одинаковы только с частичными отличиями, поэтому в некоторых случаях угаданная или обнаруженная кодировка может быть ложной, но в то же время быть правдой! Что касается Windows-1252 и ISO-8859-1. (см. последний абзац в разделе 5.2 моего доклада).

Какую библиотеку использовать?

На момент написания этой статьи появляются три библиотеки:

  • GuessEncoding
  • ICU4j
  • juniversalchardet

Я не включаю Apache Any23, потому что он использует ICU4j 3.4 под капотом.

Как определить, какая из них обнаружила правильную кодировку (или как можно ближе)?

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

Как получить ответ?

Каждому ответу может быть присвоена одна точка. Чем больше точек ответа, тем больше уверенности в обнаруженной кодировке. Это простой метод подсчета очков. Вы можете уточнить другие.

Есть ли какой-нибудь пример кода?

Вот полный фрагмент, реализующий стратегию, описанную в предыдущих строках.

Улучшения: Метод guessEncoding полностью считывает входной поток. Для больших входных потоков это может быть проблемой. Все эти библиотеки будут читать весь входной поток. Это означало бы значительное потребление времени для обнаружения кодировки.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *