Перейти к содержимому

C как узнать кодировку файла

  • автор:

Как узнать кодировку файла? C #

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

4 ответа

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

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

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

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

How to find out the Encoding of a File? C#

Well i need to find out which of the files i found in some directory is UTF8 Encoded either ANSI encoded to change the Encoding in something else i decide later. My problem is.. how can i find out if a file is UTF8 or ANSI Encoded? Both of the encodings are actually posible in my files.

5 Answers 5

There is no reliable way to do it (since the file might be just random binary), however the process done by Windows Notepad software is detailed in Micheal S Kaplan’s blog:

  1. Check the first two bytes; 1. If there is a UTF-16 LE BOM, then treat it (and load it) as a «Unicode» file; 2. If there is a UTF-16 BE BOM, then treat it (and load it) as a «Unicode (Big Endian)» file; 3. If the first two bytes look like the start of a UTF-8 BOM, then check the next byte and if we have a UTF-8 BOM, then treat it (and load it) as a «UTF-8» file;
  2. Check with IsTextUnicode to see if that function think it is BOM-less UTF-16 LE, if so, then treat it (and load it) as a «Unicode» file;
  3. Check to see if it UTF-8 using the original RFC 2279 definition from 1998 and if it then treat it (and load it) as a «UTF-8» file;
  4. Assume an ANSI file using the default system code page of the machine.

There is no great way to detect an arbitrary ANSI code page, though there have been some attempts to do this based on the probability of certain byte sequences in the middle of text. We don’t try that in StreamReader. A few file formats like XML or HTML have a way of specifying the character set on the first line in the file, so Web browsers, databases, and classes like XmlTextReader can read these files correctly. But many text files don’t have this type of information built in.

C как узнать кодировку файла

Здравствуйте, Аноним, Вы писали:

А>Нужно прочитать файл, обработать и сохранить в другой файл — с точно такой же кодировкой. Кодировка может быть UTF-8/32 (с BOM или без), ASCII.

Поправка. UTF-32 не нужен, только UTF-16/8 и ASCII.

От: Pavel Dvorkin
Дата: 29.04.11 11:25
Оценка: 62 (1)

Здравствуйте, Аноним, Вы писали:

А>Нужно прочитать файл, обработать и сохранить в другой файл — с точно такой же кодировкой. Кодировка может быть UTF-8/32 (с BOM или без), ASCII.
А>Есть идеи?

От: ZmeyNet
Дата: 30.04.11 16:14
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Нужно прочитать файл, обработать и сохранить в другой файл — с точно такой же кодировкой. Кодировка может быть UTF-8/32 (с BOM или без), ASCII.
А>Есть идеи?

C как узнать кодировку файла

Вот схема:
объявляем два массива
WinCounts : array [char] of integer; // Количество символов в кодировке Win
DosCounts : array [char] of integer; // Количество сисволов в кодировке DOS

Очередную строку файла обработываем:

if length(S) = 0 then exit;

SetLength(S2, length(S));
OEMToChar(PChar(S), PChar(S2)); /// DOWtoWIN
S1 := Upper(S);
S2 := Upper(S2);
for i:=1 to length(S1) do begin
Inc(WinCounts[S1[i]]);
Inc(DosCounts[S2[i]]);
end;

т.е. увеличиваем количество символов в обеих кодировках.
Чем больше строк обработано, тем лучше, но достаточно даже одной строки.

После обработки части файла:

M := (WinCounts[‘О’] + WinCounts[‘Т’] + WinCounts[‘Е’] + WinCounts[‘H’] + WinCounts[‘А’]);
if (DosCounts[‘О’] + DosCounts[‘Т’] + DosCounts[‘Е’] + DosCounts[‘H’] + DosCounts[‘А’]) > M
then CodePage := cpDOS;

То есть я не достаточно подорбно объяснил. Итак. Сначала нужно узнать в какой кодировке файл. Для этого его нужно просканировать (или хотя-бы несколько строк). Для каждой строки файла S

S1 = upper(S) — исходная строка
S2 = upper(OEMtoChar(S)) — та же строка в другой кодировке

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

Увеличиваем количество символов
for i:=1 to length(S1) do begin
Inc(WinCounts[S1[i]]);
Inc(DosCounts[S2[i]]);
end;

Когда все строки проанализированы, проверяем частоты встречаемости символов ОТЕНАР в обеих кодировках

M := (WinCounts[‘О’] + WinCounts[‘Т’] + WinCounts[‘Е’] + WinCounts[‘H’] + WinCounts[‘А’]);

if (DosCounts[‘О’] + DosCounts[‘Т’] + DosCounts[‘Е’] + DosCounts[‘H’] + DosCounts[‘А’]) > M
then CodePage := cpDOS;
else CodePage := cpWIN;

И уже теперь, если cpDOS, то переводим строку в кодировку WIN.

Как уже было замечено, 100% определения не достигнуть. Но, по моим наблюдениям такой алгоритм правильно срабатывал по одной строке.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *