Действительно ли возможно надежно автодекодировать пользовательские файлы к Unicode? [C#]

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

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

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

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

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

  1. Действительно ли осведомленное о BOM обнаружение достаточно для подавляющего большинства файлов?
  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, но я хочу решение быть расширяемым, если это возможно.
  • Мой существующий набор входных файлов не почти достаточно широк для раскрытия всех проблем, которые произойдут с живыми файлами.
  • Хотя файлы, которые я пытаюсь декодировать, являются "текстом", я думаю, что они часто создаются w/methods, которые оставляют посторонние символы в файлах. Следовательно "допустимые" файлы не могут быть "чистыми". О, радость.

Спасибо.

8
задан Deduplicator 16 April 2014 в 00:11
поделиться

5 ответов

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

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

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

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

3
ответ дан 5 December 2019 в 21:18
поделиться

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

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

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

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

2
ответ дан 5 December 2019 в 21:18
поделиться

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

1
ответ дан 5 December 2019 в 21:18
поделиться

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

1
ответ дан 5 December 2019 в 21:18
поделиться

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

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

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

0
ответ дан 5 December 2019 в 21:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: