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

Обновлено: 20.08.2024

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

Представляет кодировку символов.

Примеры

В следующем примере строка из одной кодировки преобразуется в другую.

Комментарии

Обратите внимание, что Encoding предназначено для работы с символами Юникода вместо произвольных двоичных данных, таких как байтовые массивы. Если необходимо закодировать произвольные двоичные данные в текст, следует использовать протокол, такой как uuencode, который реализуется такими методами, как Convert.ToBase64CharArray .

ASCIIEncodingкодирует символы Юникода как однострочные 7-разрядные символы ASCII. Эта кодировка поддерживает только символьные значения в диапазоне от U + 0000 до U + 007F. Кодовая страница 20127. Также доступно через ASCII свойство.

UTF7Encodingкодирует символы Юникода в кодировке UTF-7. Эта кодировка поддерживает все значения символов Юникода. Кодовая страница 65000. Также доступно через UTF7 свойство.

UTF8Encodingкодирует символы Юникода в кодировке UTF-8. Эта кодировка поддерживает все значения символов Юникода. Кодовая страница 65001. Также доступно через UTF8 свойство.

UnicodeEncodingкодирует символы Юникода в кодировке UTF-16. Поддерживаются как прямой, так и обратный порядок байтов. Также доступно через Unicode свойство и BigEndianUnicode .

UTF32Encodingкодирует символы Юникода в кодировке UTF-32. Поддерживаются как с прямым порядком байтов (кодовая страница 12000), так и с обратным порядком байтов (кодовая страница 12001). Также доступно через UTF32 свойство.

EncodingКласс в основном предназначен для преобразования между различными кодировками и Юникодом. Часто один из производных классов Юникода является правильным выбором для вашего приложения.

Используйте GetEncoding метод для получения других кодировок и вызовите GetEncodings метод, чтобы получить список всех кодировок.

Список кодировок

Кодовые страницы EncodingInfo.Name , свойства которых соответствуют международным стандартам, не обязательно полностью соответствуют этому стандарту.

В следующем примере вызываются GetEncoding(Int32) GetEncoding(String) методы и для получения кодировки кодовой страницы греческого языка (Windows). Он сравнивает объекты, Encoding возвращаемые вызовами методов, чтобы показать, что они равны, а затем Maps отображает кодовую точку Юникода и соответствующее значение кодовой страницы для каждого символа в греческом алфавите.

Если данные для преобразования доступны только в последовательных блоках (например, чтение данных из потока) или если объем данных настолько велик, что необходимо разделить на меньшие блоки, следует использовать Decoder или, Encoder предоставленный GetDecoder методом или GetEncoder методом, соответственно, для производного класса.

Кодировщики UTF-16 и UTF-32 могут использовать обратный порядок байтов (самый значащий байт) или обратный порядок байтов (минимальный значащий байт). Например, Латинская прописная буква A (U + 0041) сериализуется следующим образом (в шестнадцатеричном формате):

Порядковый номер UTF-16 с обратным порядком байтов: 00 41

UTF-16 с прямым порядком байтов: 41 00

UTF-32. обратный порядок байтов: 00 00 00 41

UTF-32, прямой порядок байтов: 41 00 00 00

Обычно более эффективно хранить символы Юникода с помощью собственного порядка байтов. Например, лучше использовать прямой порядок байтов на платформах с прямым порядком байтов, таких как компьютеры Intel.

GetPreambleМетод извлекает массив байтов, включающий метку порядка байтов (BOM). Если этот массив байтов имеет префикс в закодированном потоке, он позволяет декодеру указывать используемый формат кодирования.

Дополнительные сведения о порядке байтов и метке порядка байтов см. в стандарте Юникода на домашней странице Юникода.

Обратите внимание, что классы кодирования позволяют ошибкам:

Автоматическое изменение символа на символ "?".

Используйте символ "лучше подходит".

Измените поведение приложения с помощью EncoderFallback DecoderFallback классов и с помощью символа замены Юникода U + FFFD.

При любой ошибке потока данных следует вызывать исключение. Приложение либо использует флаг "throwOnError", если применимо, либо использует EncoderExceptionFallback DecoderExceptionFallback классы и. Резервные стратегии наилучшего соответствия часто не рекомендуются, так как это может привести к потере или путанице данных и медленнее, чем простые замены символов. Для кодировок ANSI наилучшее поведение используется по умолчанию.

Конструкторы

Инициализирует новый экземпляр класса Encoding.

Инициализирует новый экземпляр класса Encoding, соответствующий заданной кодовой странице.

Инициализирует новый экземпляр класса Encoding, соответствующий заданной кодовой странице, с использованием указанных стратегий резервирования кодировщика и декодера.

Свойства

Получает кодировку для набора символов ASCII (7-разрядных).

Получает кодировку для формата UTF-16 с обратным порядком байтов.

При переопределении в производном классе получает идентификатор кодовой страницы текущего объекта Encoding.

Возвращает или задает объект DecoderFallback для текущего объекта Encoding.

Возвращает или задает объект EncoderFallback для текущего объекта Encoding.

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

При переопределении в производном классе получает значение, указывающее, может ли текущая кодировка использоваться клиентами браузера для отображения содержимого.

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

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

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

При переопределении в производном классе получает значение, указывающее, является ли текущая кодировка доступной только для чтения.

При переопределении в производном классе получает значение, указывающее, используются ли в текущей кодировке однобайтовые кодовые точки.

Возвращает кодировку для набора символов Latin1 (ISO-8859-1).

При переопределении в производном классе возвращает диапазон, содержащий последовательность байтов, задающую используемую кодировку.

Получает кодировку для формата UTF-16 с прямым порядком байтов.

Получает кодировку для формата UTF-32 с прямым порядком байтов.

Получает кодировку для формата UTF-7.

Получает кодировку для формата UTF-8.

При переопределении в производном классе получает кодовую страницу операционной системы Windows, наиболее точно соответствующую текущей кодировке.

Методы

При переопределении в производном классе создается неполная копия текущего объекта Encoding.

Преобразует весь массив байтов из одной кодировки в другую.

Преобразует диапазон байтов в массиве байтов из одной кодировки в другую.

Создает Stream, который служит для перекодирования данных между внутренним Encoding и внешним Encoding, как и в случае с Convert(Encoding, Encoding, Byte[]).

Определяет, равен ли указанный объект Object текущему экземпляру.

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

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

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

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

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

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

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

При переопределении в производном классе кодирует все символы из указанного массива символов в последовательность байтов.

При переопределении в производном классе кодирует набор символов из указанного массива символов в последовательность байтов.

При переопределении в производном классе кодирует набор символов из указанного массива символов в указанный массив байтов.

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

При переопределении в производном классе кодирует все символы заданной строки в последовательность байтов.

При переопределении в производном классе кодирует в массив байтов количество символов, заданных count в указанной строке, начиная с указанного index .

При переопределении в производном классе кодирует набор символов из заданной строки в заданный массив байтов.

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

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

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

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

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

При переопределении в производном классе декодирует все байты из указанного массива байтов в набор символов.

При переопределении в производном классе декодирует последовательность байтов из указанного массива байтов в набор символов.

При переопределении в производном классе декодирует последовательность байтов из указанного массива байтов в указанный массив символов.

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

При переопределении в производном классе получает декодер, который преобразует последовательность байтов в последовательность символов.

При переопределении в производном классе получает кодировщик, который преобразует последовательность символов Юникода в закодированную последовательность байтов.

Возвращает кодировку, связанную с указанным идентификатором кодовой страницы.

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

Возвращает кодировку, связанную с указанным именем кодовой страницы.

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

Возвращает массив, содержащий все кодировки.

Возвращает хэш-код текущего экземпляра.

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

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

При переопределении в производном классе возвращает последовательность байтов, задающую используемую кодировку.

При переопределении в производном классе декодирует указанное количество байтов начиная с указанного адреса в строку.

При переопределении в производном классе декодирует все байты из указанного массива байтов в строку.

При переопределении в производном классе декодирует последовательность байтов из указанного массива байтов в строку.

При переопределении в производном классе декодирует все байты из указанного диапазона байтов в строку.

Возвращает объект Type для текущего экземпляра.

Получает значение, которое указывает, является ли текущая кодировка всегда нормализованной с использованием формы нормализации по умолчанию.

При переопределении в производном классе получает значение, которое указывает, является ли текущая кодировка всегда нормализованной с использованием заданной по умолчанию формы нормализации.

Создает неполную копию текущего объекта Object.

Регистрирует поставщик кодировки.

Возвращает строку, представляющую текущий объект.

Методы расширения

Кодирует указанный объект ReadOnlySequence<T> в массив Byte, используя указанную кодировку Encoding.

Декодирует указанный объект ReadOnlySequence<T> в byte с использованием указанной кодировки Encoding и записывает результат в writer .

Кодирует указанный объект ReadOnlySequence<T> в byte с использованием указанной кодировки Encoding и выводит результат в bytes .

Кодирует указанный объект ReadOnlySpan<T> в byte с использованием указанной кодировки Encoding и записывает результат в writer .

Декодирует указанный объект ReadOnlySequence<T> в char с использованием указанной кодировки Encoding и записывает результат в writer .

Декодирует указанный объект ReadOnlySequence<T> в char с использованием указанной кодировки Encoding и выводит результат в chars .

Декодирует указанный объект ReadOnlySpan<T> в char с использованием указанной кодировки Encoding и записывает результат в writer .

Декодирует указанный объект ReadOnlySequence<T> в String, используя указанную кодировку Encoding.

Есть ли способ узнать, какую кодировку использует файл?

Единственный способ сделать это надежно - найти метки порядка байтов в начале текстовый файл. (Этот blob в более общем смысле представляет собой порядок байтов используемой кодировки символов, но также и кодировку - например, UTF8, UTF16, UTF32). К сожалению, этот метод работает только для кодировок на основе Unicode и ничего до этого (для которых необходимо использовать гораздо менее надежные методы).

Тип StreamReader поддерживает обнаружение этих метки для определения кодировки - вам просто нужно передать флаг параметру как таковой:

Затем вы можете проверить значение stremReader.CurrentEncoding , чтобы определить кодировку, используемую файлом. Однако обратите внимание, что если метки байтовой кодировки не существуют, то CurrentEncoding по умолчанию будет Encoding.Default .

Нет отличного способа обнаружить произвольную кодовую страницу ANSI, хотя были попытки сделать это, основываясь на вероятности наличия определенных последовательностей байтов в середине текста. Мы не пытаемся этого сделать в StreamReader. Некоторые форматы файлов, такие как XML или HTML, позволяют указать набор символов в первой строке файла, чтобы веб-браузеры, базы данных и классы, такие как XmlTextReader, могли правильно читать эти файлы. Но многие текстовые файлы не содержат такой информации.

Невозможно сделать это со 100% надежностью. Вы должны решить, какой компромисс между стоимостью и точностью вам удобен. В этом ответе я обсуждаю многие возможные алгоритмы (с плюсами и минусами): Сценарий поиска PowerShell, игнорирующий двоичные файлы

Как указал Ричард, полностью надежного способа сделать это нет. Однако вот несколько потенциально полезных ссылок:

Некоторое время назад я написал это на C ++, и это стало довольно сложно. Вот что я делаю (принимаю первое, что подходит):

  • Найдите метки порядка байтов
  • Проверить правильность текста UTF-32 BE / LE
  • Проверьте правильность текста UTF-16 BE / LE
  • Проверьте правильность текста UTF-8
  • Предположить текущую кодовую страницу

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

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

Единственная возможность помочь в этом случае - позволить пользователю выбрать кодовую страницу (с точки зрения пользователя лучше всего было бы позволить пользователю изменить предполагаемую кодировку, когда он увидит текст).

Он работает нормально на тестовом наборе, но, конечно, возможны неправильные интерпретации, если они маловероятны.

Кодовые страницы могут быть определены путем статистического анализа текста (например, частота пар и троек символов, содержащих символы, отличные от ASCII, или списки слов на разных языках, но я не нашел подходящего подхода для этого.

IsTextUnicode в Win32 заведомо плохой, он проверяет только для UTF-16 и, вероятно, является виновником того, что «куст спрятал факты» в блокноте.

Как писал Петерхен, вы должны написать «куст, скрыть факты» в Notepad.exe, сохранить и снова открыть его, чтобы увидеть, насколько сложно обнаружить кодировку.

  • Сначала проверьте спецификацию, используйте ее, если она предоставлена
  • В противном случае проверьте, какой кодировкой Unicode МОЖЕТ быть файл.
  • Для каждой найденной возможной кодировки Unicode проверьте, ВЕРОЯТНО ли эта кодировка для предоставленных данных (при условии, что в основном это западноевропейский контент).
  • Если "возможные" кодировки Unicode маловероятны, используйте предоставленную кодовую страницу / кодировку по умолчанию.

Извините, что этот ответ так поздно - я только недавно очистил класс и разместил его в Интернете.

Ну, мне нужно выяснить, какой из файлов, которые я нашел в каком-то каталоге, кодируется UTF8 либо ANSI, чтобы изменить кодировку в чем-то другом, что я решу позже. Моя проблема.. как я могу узнать, закодирован ли файл UTF8 или ANSI? Обе кодировки на самом деле возможны в моих файлах.

нет надежного способа сделать это (так как файл может быть просто случайным двоичным), однако процесс, выполняемый программным обеспечением Windows Notepad, подробно описан в блоге Micheal S Kaplan:

  1. проверить первые два байта; 1. Если есть UTF-16 LE BOM, то обработайте его (и загрузите) как файл "Unicode; 2. Если есть UTF-16 be BOM, то обработайте его (и загрузите его) как " Unicode (Big Прямой файл)" ; 3. Если первые два байта выглядят как начало спецификации UTF-8, Проверьте следующий байт, и если у нас есть спецификация UTF-8, то обработайте ее (и загрузите) как файл "UTF-8";
  2. проверьте с IsTextUnicode, чтобы увидеть, если эта функция думает, что это BOM-less UTF-16 LE, если да, то обработайте его (и загрузите его) как файл" Unicode";
  3. Проверьте, использует ли он UTF-8 Исходное определение RFC 2279 с 1998 года, и если он затем обрабатывает его (и загружает его) как файл "UTF-8";
  4. предположим, файл ANSI, используя системную кодовую страницу по умолчанию машины.

нет большого способа обнаружить произвольная кодовая страница ANSI, хотя там были некоторые попытки сделать это основываясь на вероятности определенного последовательности байтов в середине текста. Мы не пробуем это в StreamReader. Ля несколько форматов файлов, таких как XML или HTML способ задания набора символов на первой строке в файле, so Web браузеры, базы данных, и такие занятия, как XmlTextReader может читать эти файлы правильно. Но многие текстовые файлы не постройте этот тип информации в.

Unicode / UTF8 / UnicodeBigEndian считаются различными типами. ANSI считается таким же, как UTF8.

см. эти две статьи codeproject - нетривиально узнать кодировку файла просто из содержимого файла:

Собственно проблема заключается в том, что есть 2 типа файлов, в одних текст сохранён в кодировке UTF8 в других - Windows-1251 и необходимо переконвертировать файлы Windows-1251 в UTF8, с UTF8 ничего не делать. Как определить кодировку файла? Я Не знаю заведомо в какой кодировке сохранён файл.

StreamReader sr = new StreamReader(s, true); //true - определить кодировку, но sr.CurrentEncoding показывает что кодировка Encoding.UTF8

Префикс? типа имя файла вида utf8_144545.txt, win-1251_3243222.txt?? нет все файлы имеют имя \d<1,5>.txt

Есть только фолдер с файлами различной кодировки, необходимо чтобы все файлы стали в UTF8.

Префикс? типа имя файла вида utf8_144545.txt, win-1251_3243222.txt?? нет все файлы имеют имя \d<1,5>.txt

Есть только фолдер с файлами различной кодировки, необходимо чтобы все файлы стали в UTF8.


Я про первые 3 байта в файле.

[FONT="Courier New"][SIZE="2"]UTF-8 (EF BB BF)
UTF-16 big-endian (FE FF)
UTF-16 little-endian (FF FE)
UTF-32 big-endian (00 00 FE FF)
UTF-32 little-endian (FF FE 00 00)[/SIZE][/FONT]

Читаешь первые три байта файла. И если они равны 0xEF 0xBB 0xBF, то файл должен быть в UTF-8. Правда, это условие не всегда выполняется.

Ну тогда, поскольку символы в UTF-8 определяются последовательностями от 1 до 4 байт, можно попробовать анализ по маске первого байта в коде. В общем случае задача непростая, но зная что далеко не каждая комбинация символов допустима в UTF8, полагаясь на интернациональные символы можно попробовав раскодировать исходный файл по UTF8 предположить его кодировку.

Я про первые 3 байта в файле.


Читаешь первые три байта файла. И если они равны 0xEF 0xBB 0xBF, то файл должен быть в UTF-8. Правда, это условие не всегда выполняется.


Что-то мне говорить, что это BOM ;)

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


На сколько я помню как раз утф-8 проще всего и распознать. На практике в утф-8 используется от 1 до 4 байт. Два первых старших бита в первом байте всегда установлены в единицу. С учетом BOM-а нужно прочитать первых 7 байт. Для полной гарантии и определения размерности байт на символ конечно лучше прочесть все же первые 11. Собственно по ним и будет видно.

М-м-м.. Все же скажу хоть первый раз не собрался :). Насколько помню я, по стандарту, UTF8 может отводить на 1 символ до 6 байт. Вот даж прям счаз лезть проверять лень :). Ну просто не факт что последовательности из5-6 байт за чем-то закреплены. А английский текст на UTF8 выглядит аналогично ANSI, поэтому я и говорю что задача непростая (имеется ввиду нет у нее четкого алгоритмического решения). А вот если символ из некоей национальной кодировки (занимает несколько байт) то да, вплоть до последнего байта некоторые биты в начальных байтах играют роль флагов. Но эти же байты не запрещены в ANSI что делает отнесение потока к ANSI/UTF не совсем тривиальной задачей

Теоретически, текст может отличаться только тем, что в UTF-8 невозможны некоторые комбинации байтов, которые используются в ANSI.

Таким образом, можно попытаться переводить текст (с неизвестной кодировкой) из UTF-8 в ANSI и ловить исключение. Если текст был в кодировке ANSI, то может быть сгенерировано исключение.

Это ленивый метод, который в теории может сработать.

Таким образом, можно попытаться переводить текст (с неизвестной кодировкой) из UTF-8 в ANSI и ловить исключение. Если текст был в кодировке ANSI, то может быть сгенерировано исключение.


Ну вообщем я пропагандировал этот же подход. Дополнительно, если возможно основываться на некоем формате/содержимом обрабатываемых файлов можно искать какие-либо шаблоны. Например распространенные слова языка.

Читайте также: