Перекодировать в UTF-8 с BOM

Рейтинг: 1Ответов: 2Опубликовано: 03.05.2015

Есть дерево папок исходников (.cpp, .h). Большинство исходников имеют кодировку UTF-8 без BOM и возможно остались исходники в CP1251. Нужно все перевести в UTF-8 с BOM, причём сохранить структуру папок.

Пробовал UTFCast Express, но он UTF-8 без BOM распознал как ANSI. В результате перекодировал в UTF-8 второй раз, превратив исходники в кракозябры в любой кодировке.

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

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

Ответы

▲ 3Принят

Давайте напишем пару вспомогательных методов (на C#):

Encoding strictUtf8Encoding =
    new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);

Encoding strictCp1251Encoding =
    Encoding.GetEncoding(
                1251,
                new EncoderExceptionFallback(),
                new DecoderExceptionFallback());

string TryDecodeFileContent(byte[] bytes, Encoding encoding)
{
    try
    {
        var preambleBytes = encoding.GetPreamble();
        bool startWithPreamble =
                preambleBytes.Length != 0 &&
                Enumerable.SequenceEqual(preambleBytes, bytes.Take(preambleBytes.Length));
        int startByte = startWithPreamble ? preambleBytes.Length : 0;
        return encoding.GetString(bytes, startByte, bytes.Length - startByte);
    }
    catch (Exception)
    {
        return null;
    }
}

string TryReadFile(string filename)
{
    var bytes = File.ReadAllBytes(filename);
    return TryDecodeFileContent(bytes, strictUtf8Encoding) ??
           TryDecodeFileContent(bytes, strictCp1251Encoding);
}

С ними должно быть легко:

var text = TryReadFile(filename);
if (text == null)
    Console.WriteLine("Needs attention: " + filename);
else    
    File.WriteAllText(filename, text, Encoding.UTF8);

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

▲ 2

Вы же программист. Напишите программу в несколько строчек, которая пройдётся по иерархии. Если у вас в коде символы win-1251, а возможных кодировок только две, то проверка кодировки простая: загрузить как UTF-8, загрузить как win-1251; одна из версий должна дать текст, в котором только символы из нужных диапазонов и никакого мусора. Переводите в нужную кодировку. И рекурсией по папкам.

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