Как определить кодировку текстового файла(C#) - CodeHelper

Как определить кодировку текстового файла(C#)

1

Вопрос в названии, нужно как то определять кодировку текстового файла и уже считывать данные на её основании.

Новые ответы


0

Если речь идёт о кодировке UTF-8, то можно использовать проект Utf8Checker. Проект состоит из одного класса (и интерфейса к нему), который и делает всю работу.

1

И все же мне удалось решить проблему

Сначала код:

BinaryReader instr = new BinaryReader(File.OpenRead(path));
byte[] data = instr.ReadBytes((int)instr.BaseStream.Length);
instr.Close();

// определяем BOM (EF BB BF)
if (data.Length > 2 && data[0] == 0xef && data[1] == 0xbb && data[2] == 0xbf) {
    if (data.Length != 3) return Encoding.UTF8.GetString(data, 3, data.Length - 3);
    else return "";
}

int i = 0;
while (i < data.Length - 1) {
    if (data[i] > 0x7f) { // не ANSI-символ
        if ((data[i] >> 5) == 6) {
            if ((i > data.Length - 2) || ((data[i + 1] >> 6) != 2))
                return Encoding.GetEncoding(1251).GetString(data);
            i++;
        } else if ((data[i] >> 4) == 14) {
            if ((i > data.Length - 3) || ((data[i + 1] >> 6) != 2) || ((data[i + 2] >> 6) != 2))
                return Encoding.GetEncoding(1251).GetString(data);
            i += 2;
        } else if ((data[i] >> 3) == 30) {
            if ((i > data.Length - 4) || ((data[i + 1] >> 6) != 2) || ((data[i + 2] >> 6) != 2) || ((data[i + 3] >> 6) != 2))
                return Encoding.GetEncoding(1251).GetString(data);
            i += 3;
        } else {
            return Encoding.GetEncoding(1251).GetString(data);
        }
    }
    i++;
}

return Encoding.UTF8.GetString(data);

Теперь немного поясню: Сиволы в UTF-8 кодируются последовательностями длиной от 1 до 4 байт (октетов).

Вот в таком формате:

U+000000-U+00007F: 0xxxxxxx (ANSI)
U+000080-U+0007FF: 110xxxxx 10xxxxxx (сюда входит кириллица)
U+000800-U+00FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U+010000-U+10FFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

По маске первого октета определяется общее число октет в последовательности, а затем они проверяются на соответствие маске 10xxxxxx. Если какой-то байт не соответсвует маске, значит кодировка отличная от UTF-8 (в моем случае win1251).

Код, конечно, громоздкий, но для демонтрации самого алгоритма вполне достаточный

Источник


v1.7.123.556
© 2009—2010 CodeHelper FAQ | О сайте | Обратная связь | История изменений | Статьи
Creative Commons LicenseМатериалы сайта распространяются под лицензией Creative Commons Attribution-Share Alike 3.0 Unported.