как-то не сталкивался, а тут файл с битыми данными попросили восстановить, ну как с битыми - часть данных стала типа того: "Ðîóòåð" вместо "Роутер".
Сначала разобрался, как получить читаемость, потом стало интереснее. Все примеры, включая ГэПэТэ давали это:
var Bytes := TEncoding.ANSI.GetBytes(AStr);
Result := TEncoding.GetEncoding(1251).GetString(Bytes);
Всё работает, в смысле перекодировки, но Delphi честно сообщает, что утечка памяти TMBCSEncoding на второй строке примера.
Вот код и рабочий, и без утечки, который я получил после разбирательств с проблемой:
var Bytes := TEncoding.ANSI.GetBytes(AStr);
var Encoding1251 := TEncoding.GetEncoding(1251);
Result := Encoding1251.GetString(Bytes);
Encoding1251.Free;
Как говорится, какого фига такого примера не было? Или я что-то не понимаю? 😀
Для тех, что этого не касался - в первой строке TEncoding.ANSI всё нормально. Там для стандартных кодировок в классе есть классовые переменные, которые сами особождаются, а вот кастомные кодировки - на ответственность прогера
Второй вопрос, данные восстановлены, но это был небольшой объём и ручной режим для визуального контроля:
Итак, данные восстановлены, но в ручном режиме, т.к. часть данных уже была читаема, а часть - нет. Хотелось бы автоматизировать. 2 варианта есть с данными после прогона через перекодировщик: var Bytes := TEncoding.ANSI.GetBytes(AStr); Result := TEncoding.GetEncoding(1251).GetString(Bytes); 1. Было "Ðîóòåð", стало "Роутер" - восстановили 2. Было "Роутер", стало "??????" - испортили читаемые Там по определению не могут быть знаки вопроса, т.к. это изначально названия файлов, поэтому первая мысль - проверять на появления знака "?". Но может есть более красивое и логичное определение и решение?
Между делом вернулся к задаче и пришла такая мысль: если мы назад конвертнём полученный текст и не получим оригинал, значит мы что-то испортили и конвертить не надо. Кто имел дело с кодировками - какие могут быть подводные камни в идее? var Encoding1251 := TEncoding.GetEncoding(1251); try var sText := edtConvertSource.Text; var Bytes := TEncoding.ANSI.GetBytes(sText); var sResult := Encoding1251.GetString(Bytes); Bytes := Encoding1251.GetBytes(sResult); var sResult2 := TEncoding.ANSI.GetString(Bytes); if SameText(sText, sResult2) then edtConvertDestination.Text := sResult else edtConvertDestination.Text := sText; finally Encoding1251.Free; end;
кодировки необязательно совпадают по набору символов
Обсуждают сегодня