Определить кодировку строки в C#
скажем, у меня есть строка имени файла, но я не знаю, закодирована ли она в Unicode UTF-16 или системная кодировка по умолчанию, как узнать?
8 ответов
Проверьте Utf8Checker это простой класс, который делает именно это в чистом управляемом коде. http://utf8checker.codeplex.com
Примечание: как уже отмечал «определить кодировку» имеет смысл только для байтовых потоков. Если у вас есть строка, она уже закодирована от кого-то, кто уже знал или угадал кодировку, чтобы получить строку в первую очередь.
приведенный ниже код имеет следующие особенности:
- обнаружение или попытка обнаружения UTF-7, UTF-8/16/32 (bom, no bom, little & big endian)
- возвращается к локальной кодовой странице по умолчанию, если кодировка Unicode не найдена.
- обнаруживает (с высокой вероятностью) файлы unicode с отсутствующей спецификацией/сигнатурой
- Поиск charset=xyz и encoding=xyz внутри файла, чтобы помочь определить кодировку.
- для сохранения обработки, вы можете «вкус» файла (определенное количество байтов).
- кодировка и декодированный текстовый файл возвращается.
- чисто байтовое решение для эффективности
Как говорили другие, никакое решение не может быть идеальным (и, конечно, нельзя легко различать различные 8-битные расширенные кодировки ASCII, используемые во всем мире), но мы можем получить «достаточно хорошо», особенно если разработчик также представляет пользователю список альтернативных кодировок, как показано здесь: какова наиболее распространенная кодировка каждого языка?
полный список кодировок можно найти с помощью Encoding.GetEncodings();
Это зависит от того, откуда строка «пришла». Строка .NET-это Unicode (UTF-16). Единственный способ может быть другим, если вы, скажем, читаете данные из базы данных в массив байтов.
Джон Скит строки в C# и .NET является отличным объяснением строк .NET.
Я знаю, что это немного поздно , но чтобы быть ясным:
строка на самом деле не имеет кодировки. в .NET строка a представляет собой коллекцию объектов char. По сути, если это строка, то она уже декодирована.
однако, если Вы читаете содержимое файла, который состоит из байтов, и хотите преобразовать его в строку, то необходимо использовать кодировку файла.
.Net включает в себя кодирование и декодирование классы: в ASCII, UTF7, utf8 в, кодировках utf32 и больше.
большинство этих кодировок содержат определенные метки порядка байтов,которые можно использовать для различения типа кодировки.
система классов .NET.ИО.StreamReader может определить кодировку, используемую в потоке, прочитав эти метки порядка байтов;
другой вариант, очень поздно, к сожалению:
этот небольшой класс C#-only использует BOMS, если он присутствует, пытается автоматически обнаружить возможные кодировки unicode в противном случае и отступает, если ни одна из кодировок Unicode не возможна или вероятна.
похоже, что UTF8Checker, упомянутый выше, делает что-то подобное, но я думаю, что это немного шире в области-вместо просто UTF8, это также проверяет другие возможные кодировки Unicode (UTF-16 LE или BE), которые могут отсутствовать в спецификации.
надеюсь, это кому-то поможет!
мое решение заключается в использовании встроенных материалов с некоторыми резервными вариантами.
Я выбрал стратегию из ответа на другой аналогичный вопрос о stackoverflow, но я не могу найти ее сейчас.
Он сначала проверяет спецификацию, используя встроенную логику в StreamReader, если есть спецификация, кодировка будет чем-то иным, чем Encoding.Default , и мы должны доверять этому результату.
Если нет, он проверяет, является ли последовательность байтов допустимой последовательностью UTF-8. если это так, он угадает UTF-8 как кодировка, а если нет, опять же, кодировка ASCII по умолчанию будет результатом.
Примечание: это был эксперимент, чтобы увидеть, как кодировка UTF-8 работает внутри. решение, предложенное vilicvane, чтобы использовать UTF8Encoding объект, инициализированный для создания исключения при сбое декодирования, намного проще и в основном делает то же самое.
Я написал этот фрагмент кода, чтобы различать UTF-8 и Windows-1252. Однако он не должен использоваться для гигантских текстовых файлов, поскольку он загружает все это в память и сканирует полностью. Я использовал его для .файлов субтитров SRT, просто чтобы иметь возможность сохранять их в кодировке, в которой они были загружены.
кодировка, заданная функции как ref, должна быть 8-битной резервной кодировкой для использования в случае обнаружения файла как недопустимого UTF-8; как правило, в системах Windows это будет Windows-1252. Это не делает ничего необычного, как проверка фактических допустимых диапазонов ascii, хотя и не обнаруживает UTF-16 даже в порядке байтов отметка.
в основном, битовый диапазон первого байта определяет, сколько после него являются частью сущности UTF-8. Эти байты после него всегда находятся в одном и том же битовом диапазоне.
How can I detect the encoding/codepage of a text file?
In our application, we receive text files ( .txt , .csv , etc.) from diverse sources. When reading, these files sometimes contain garbage, because the files where created in a different/unknown codepage.
Is there a way to (automatically) detect the codepage of a text file?
The detectEncodingFromByteOrderMarks , on the StreamReader constructor, works for UTF8 and other unicode marked files, but I’m looking for a way to detect code pages, like ibm850 , windows1252 .
Thanks for your answers, this is what I’ve done.
The files we receive are from end-users, they do not have a clue about codepages. The receivers are also end-users, by now this is what they know about codepages: Codepages exist, and are annoying.
Solution:
- Open the received file in Notepad, look at a garbled piece of text. If somebody is called François or something, with your human intelligence you can guess this.
- I’ve created a small app that the user can use to open the file with, and enter a text that user knows it will appear in the file, when the correct codepage is used.
- Loop through all codepages, and display the ones that give a solution with the user provided text.
- If more as one codepage pops up, ask the user to specify more text.
![]()
21 Answers 21
You can’t detect the codepage, you need to be told it. You can analyse the bytes and guess it, but that can give some bizarre (sometimes amusing) results. I can’t find it now, but I’m sure Notepad can be tricked into displaying English text in Chinese.
Specifically Joel says:
The Single Most Important Fact About Encodings
If you completely forget everything I just explained, please remember one extremely important fact. It does not make sense to have a string without knowing what encoding it uses. You can no longer stick your head in the sand and pretend that «plain» text is ASCII. There Ain’t No Such Thing As Plain Text.
If you have a string, in memory, in a file, or in an email message, you have to know what encoding it is in or you cannot interpret it or display it to users correctly.