Перекодирование неправильных имен файлов - PullRequest
0 голосов
/ 01 марта 2020

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

Я создал архив структуры каталогов на Linux машине с локалью ISO-8859-1 и распаковал ее на Windows с помощью 7zip. В результате имена файлов зашифровываются, когда я просматриваю их в Windows Explorer (и в моей программе C# тоже): где я ожидаю увидеть немецкий умляут ü это ³ - Не удивительно, поскольку имена файлов записываются в файл tar с использованием кодовой страницы ISO-8859-1, а Windows явно не знает об этом.

Я хочу исправить это, переименовав файлы в их правильные имена. Поэтому я думаю, что должен сказать программе «прочитайте имя файла, подумайте о нем как об ISO-8859-1 и верните каждый символ как символ UTF-16».

Мой код, чтобы найти правильное имя файла:

void Main()
{
    string[] files = Directory.GetFiles(@"C:\test", @"*", SearchOption.AllDirectories);
    var e1 = Encoding.GetEncoding("ISO-8859-1");
    var e2 = Encoding.GetEncoding("UTF-16");
    foreach (var f in files)
    {
        Console.WriteLine($"Source: {f}");
        var source = e1.GetBytes(f);
        var dest = Encoding.Convert(e1, e2, source);
        Console.WriteLine($"Result: {e2.GetString(dest)}");
    }
}

Результат - ничего не произошло:

Source: C:\test\Brief-mrl³.odt
Result: C:\test\Brief-mrl³.odt

Ожидаемый результат:

Source: C:\test\Brief-mrl³.odt
Result: C:\test\Brief-mrlü.odt

Когда я обмениваю e1 и e2, я получаю странные результаты. Мой мозг болит. Что я не получаю?

Редактировать: Я знаю, что ошибка была сделана ранее, но сейчас У меня неправильные имена файлов на компьютере Windows, который я надо исправить. Однако, это может быть не решаемо через класс Encoding. Я нашел это сообщение в блоге и автор заявляет

Оказывается, это не проблема с кодировкой вообще, но один и тот же адрес символа означает разные вещи для разных наборы символов.

В заключение он написал метод замены символов от 130 до 173 на указанные c, различные символы. Это не выглядит простым для меня, но возможно ли, что это единственный путь? Кто-нибудь может прокомментировать это, пожалуйста?

1 Ответ

0 голосов
/ 02 марта 2020

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

void Main()
{
    // We get the source string e.g. reading files from a directory. We see a "³" when 
    // we expect a German umlaut "ü". The reason can be a poorly configured smb share
    // on a Linux server or other problems.
    string source = "M³nch";

    // We are in a .NET program, so the source string (here in the 
    // program) is Unicode in UTF-16 encoding. I.e., the codepoints 
    // M, ³, n, c and h are encoded in UTF-16.

    byte[] bytesFromSource = Encoding.Unicode.GetBytes(source); // 
    // The source encoding is UTF-16, hence we get two bytes per character.

    // We accidently worked with the OEM850 Codepage, we now have look up the bytes of 
    // the codepoints on the OEM850 codepage: We convert our bytesFromSource to the wrong Codepage
    byte[] bytesInWrongCodepage = Encoding.Convert(Encoding.Unicode, Encoding.GetEncoding(850), bytesFromSource);

    // Here's the trick: Although converting to OEM850, we now assume that the bytes are Codepage ISO-8859-1.
    // We convert the bytes from ISO-8859-1 to Unicode.
    byte[] bytesFromCorrectCodepage = Encoding.Convert(Encoding.GetEncoding("ISO-8859-1"), Encoding.Unicode, bytesInWrongCodepage);

    // And finally we get the right character.
    string result = Encoding.Unicode.GetString(bytesFromCorrectCodepage);

    Console.WriteLine(result); // Münch
}

CAVEAT: Не запускайте этот метод над его результатами. Это может привести к непечатным символам или другим беспорядкам.

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