Можно ли надежно автоматически декодировать пользовательские файлы в Unicode? [C #] - PullRequest
8 голосов
/ 22 февраля 2010

У меня есть веб-приложение, которое позволяет пользователям загружать свой контент для обработки. Механизм обработки ожидает UTF8 (а я сочиняю XML из файлов нескольких пользователей), поэтому мне нужно убедиться, что я могу правильно декодировать загруженные файлы.

Поскольку я был бы удивлен, если бы кто-либо из моих пользователей знал, что их файлы даже были закодированы, я очень мало надеюсь, что они смогут правильно указать кодировку (декодер) ) использовать. И так, мое приложение оставлено с задачей обнаружения перед декодированием.

Это кажется такой универсальной проблемой, я удивлен, что не нашел ни возможности фреймворка, ни общего рецепта решения. Может быть, я не ищу значимых поисковых терминов?

Я реализовал обнаружение с учетом спецификации (http://en.wikipedia.org/wiki/Byte_order_mark), но я не уверен, как часто файлы будут загружаться без спецификации, чтобы указать кодировку, и это не полезно для большинства файлов, не относящихся к UTF .

Мои вопросы сводятся к:

  1. Достаточно ли обнаружения с поддержкой спецификации для подавляющего большинства файлов?
  2. В случае, если BOM-обнаружение не удается, возможно ли попробовать разные декодеры и определить, являются ли они "действительными" ? (Мои попытки указать, что ответ «нет»)
  3. При каких обстоятельствах произойдет сбой "действительного" файла в среде кодера / декодера C #?
  4. Есть ли где-нибудь хранилище, содержащее множество файлов с различными кодировками, которые можно использовать для тестирования?
  5. Хотя я специально спрашиваю о C # / .NET, я хотел бы знать ответ для Java, Python и других языков, когда в следующий раз я сделаю это.

Пока я нашел:

  • «Действительный» файл UTF-16 с символами Ctrl-S привел к тому, что кодировка UTF-8 вызвала исключение (недопустимый символ?) (Это было исключение кодировки XML.)
  • Декодирование действительного файла UTF-16 с помощью UTF-8 успешно , но дает текст с нулевыми символами. А?
  • В настоящее время я ожидаю только файлы UTF-8, UTF-16 и, возможно, ISO-8859-1, но я хочу, чтобы решение было расширяемым, если это возможно.
  • Мой существующий набор входных файлов недостаточно широк, чтобы раскрыть все проблемы, которые могут возникнуть с живыми файлами.
  • Хотя файлы, которые я пытаюсь декодировать, являются «текстовыми», я думаю, что они часто создаются с помощью методов, которые оставляют символы мусора в файлах. Следовательно, «действительные» файлы не могут быть «чистыми». О, радость.

Спасибо.

Ответы [ 5 ]

3 голосов
/ 23 февраля 2010

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

  • Если данные начинаются с спецификации, используйте ее.
  • Если данные содержат 0 байтов, скорее всего это utf-16 или ucs-32.Вы можете различить их и варианты их с прямым и младшим порядком байтов, посмотрев на позиции 0-байтов
  • Если данные могут быть декодированы как utf-8 (без ошибок),тогда вполне вероятно, что utf-8 (или US-ASCII, но это подмножество utf-8)
  • Далее, если вы хотите выйти на международный уровень, сопоставьте языковые настройки браузера с наиболее вероятной кодировкой дляэтот язык.
  • Наконец, предположим, что ISO-8859-1

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

Примечание : этот алгоритм не будет работать, если данные содержат символы мусора.Например, один мусорный байт в действующем в противном случае utf-8 приведет к сбою декодирования utf-8, что заставит алгоритм пойти по неверному пути.Возможно, вам придется принять дополнительные меры для решения этой проблемы.Например, если вы можете заранее определить возможный мусор, удалите его, прежде чем пытаться определить кодировку.(Неважно, если вы снимаете слишком агрессивно, после того, как вы определили кодировку, вы можете декодировать исходные необработанные данные, просто настроить декодеры для замены недопустимых символов вместо того, чтобы выдавать исключение.) Или считать ошибки декодирования и взвешивать их соответствующим образом,Но это, вероятно, во многом зависит от характера вашего мусора, то есть от того, какие предположения вы можете сделать.

2 голосов
/ 23 февраля 2010

Вы пытались прочитать репрезентативное сечение ваших файлов от пользователя, запустить их через вашу программу, протестировать, исправить любые ошибки и продолжить?

Я считаю, что File.ReadAllLines () довольно эффективен в самых разных приложениях, не беспокоясь о всех кодировках. Кажется, справляется с этим довольно хорошо.

Xmlreader () справился довольно хорошо, когда я понял, как правильно его использовать.

Может быть, вы могли бы опубликовать некоторые конкретные примеры данных и получить лучшие ответы.

1 голос
/ 08 марта 2010

Вы можете взглянуть на решение на основе Python, которое называется chardet . Это порт Mozilla для Python. Хотя вы не можете использовать его напрямую, его документацию стоит прочитать, как и оригинальную статью Mozilla, на которую она ссылается.

1 голос
/ 23 февраля 2010

Это хорошо известная проблема. Вы можете попытаться сделать то, что делает Internet Explorer. Это хорошая статья в CodeProject, которая описывает решение Microsoft проблемы. Однако ни одно решение не является на 100% точным, поскольку все основано на эвристиках. И также небезопасно предполагать, что будет присутствовать спецификация.

0 голосов
/ 08 марта 2010

Я столкнулся с подобной проблемой. Мне нужен скрипт powershell, который выяснил, был ли файл закодирован (в любой обычной кодировке) или нет.

Это определенно не является исчерпывающим, но вот мое решение ...

Сценарий поиска PowerShell, игнорирующий двоичные файлы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...