Как нормализовать текстовое содержимое в UTF 8 в java

У нас есть CMS, в которой есть несколько тысяч текстовых/html файлов. Оказывается, пользователи загружали файлы text/html, используя различные кодировки символов (utf-8, utf-8 w BOM, windows 1252, iso-8859-1).

Когда эти файлы считываются и записываются в ответ, наша структура CMS принудительно устанавливает charset=UTF-8 в атрибуте типа содержимого ответа.

Из-за этого любой контент, отличный от UTF-8, отображается для пользователя с искаженными символами (?, черными ромбами и т. д., когда нет правильного перевода символов из «родной» кодировки символов в UTF-8). Кроме того, к этим документам не прикреплены метаданные, указывающие кодировку. Насколько мне известно, единственный способ узнать, какая у них кодировка, — это посмотреть на них в приложении для рендеринга текста (Firefox, Notepadd++ и т. д.) и «посмотреть». " на содержание, чтобы увидеть, "выглядит" ли оно правильно.

Кто-нибудь знает, как автоматически/разумно преобразовывать файлы неизвестной кодировки в UTF-8? Я читал, что это можно сделать с помощью статистического моделирования, но это выше моей головы.

Мысли о том, как лучше всего подойти к проблеме?

Спасибо


person empire29    schedule 16.03.2010    source источник
comment
Связанные вопросы: stackoverflow.com/questions/774075/ и stackoverflow.com/questions/499010/   -  person BalusC    schedule 16.03.2010


Ответы (3)


Вы можете использовать CharsetDetector от ICU4J.

person axtavt    schedule 16.03.2010

Попробуйте расшифровать его как UTF-8. Если это не удается, найдите \x92 и, если найдете, расшифруйте как CP1252. В противном случае расшифруйте как Latin-1.

person Ignacio Vazquez-Abrams    schedule 16.03.2010
comment
Если это недопустимый UTF-8, вы можете сразу перейти к cp1252. Это имеет значение только для байтов с \x80 по \x9F, но крайне маловероятно, что кто-либо когда-либо использовал символы, указанные в ISO-8859-1 для этих байтов (все они являются бесполезными управляющими кодами). - person bobince; 16.03.2010
comment
Зачем вам проверять только один из символов расширения cp1252? Что, если текст содержит фигурные двойные кавычки (\x93, \x94), но не фигурные одинарные кавычки (\x91, \x92)? Но, как сказал @bobince, если это действительный ISO-8859-1, вы можете с уверенностью предположить, что это действительный cp1252. - person Alan Moore; 16.03.2010
comment
@bobince, Алан: Гораздо более интересное различие между cp1251 и ISO-8859-15, что, вполне вероятно, является тем, чем на самом деле являются некоторые из этих документов ISO-8859-1 - символ евро в наши дни не совсем неуместен. - person Michael Borgwardt; 17.03.2010
comment
@Michael: я должен сказать, что мне еще предстоит встретить документ 8859-15 в дикой природе. Я думаю, что это произошло слишком поздно, чтобы увидеть широкое распространение: все, кто заботился о стандартных кодировках, уже направились к UTF-8, а все остальные придерживались cp1252. - person bobince; 17.03.2010

В общем, нет возможности рассказать. Последовательность байтов 63 61 66 C3 A9 в равной степени допустима как «café» в Windows-1252, «caf├⌐» в IBM437 или «café» в UTF-8. Хотя последнее статистически более вероятно.

Если вы не хотите иметь дело со статистическими методами, подход, который работает большую часть времени, состоит в том, чтобы предположить, что все, что выглядит как UTF-8, и что все остальное находится в Windows-1252.

Или, если возможно использование UTF-16, ищите FE FF или FF FE в начале файла.

person dan04    schedule 17.03.2010