Логика работы UTF8ToSys/SysToUTF8

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Логика работы UTF8ToSys/SysToUTF8

Сообщение wwswowsogon » 18.10.2019 22:09:51

Всем здравствуйте!

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

ПРимер 1:

Код: Выделить всё
if OpenDialog1.Execute then
    begin
      if FileExists(UTF8ToSys(OpenDialog1.FileName)) then
        begin
          s_fname := OpenDialog1.FileName;

          d_fname := GetFileName(s_fname);

          if CopyFile(s_fname, d_fname, true) then
            begin

            end
              else ShowMessage('Файл ' + UTF8ToSys(d_fname) + ' не найден.');
        end
          else ShowMessage('Файл "' + UTF8ToSys(s_fname) + '" не найден.');
    end;


Пример рабочий. Понятно, что при выводе ShowMessage нужно перевести строку из UTF8 (кодировка IDE) в Ansi (кодировка системы). Но почему при получении имени файла из OpenDialog мы используем ту же функцию, а не наоборот, SysToUTF8?

Пример 2:

В коде есть процедура загрузки bmp/jpeg:

Код: Выделить всё
s_fname := OpenDialog1.FileName;
            img_fname := GetFileName(s_fname);

              img_ext := UTF8LowerCase(GetExt(img_fname));

full_fname := 'data\' + img_fname;

ApplyBMPPreview(UTF8ToSys(full_fname));


сама процедура такая:

Код: Выделить всё
procedure ApplyBMPPreview(SFname: String);
var
  //SourceImage
  SI: Graphics.TBitmap;
begin

  SI := Graphics.TBitmap.Create;

  if FileExists(UTF8ToSys(SFname)) then SI.LoadFromFile(SFname)
    else
      begin
        ShowMessage('Файл ' + UTF8ToSys(SFname) + ' не найден.');
        SI.LoadFromFile('textures\std\img1.bmp');
        Exit;
      end;


и она работает именно в таком виде.
Получается, что мы для функции FileExists в данном случае ДВАЖДЫ применяем UTF8ToSys, а для SI.LoadFromFile - один раз. Функции требуют разных кодировок?
В других местах кода для FileExists было достаточно один раз применить UTF8ToSys. Чего я не понимаю?
Когда таких мест в коде много, становится реально трудно жить.

Прочитал соответствующую статью, но не очень помогло.
wwswowsogon
постоялец
 
Сообщения: 152
Зарегистрирован: 23.12.2008 20:41:37

Re: Логика работы UTF8ToSys/SysToUTF8

Сообщение iskander » 19.10.2019 09:36:04

Кажется после выхода FPC-3.0.0 и LCL-2.0.0 в большинстве случаев эти перекодировки стали не нужны.
К примеру вот такой обработчик(FPC-3.3.1, Lazarus-2.0.5, mmInfo это TMemo):
Код: Выделить всё
procedure TfrmMain.btTestClick(Sender: TObject);
type
  String1251 = type string(1251);
var
  FileName,
  CopyName: string;
  FileName1251: String1251;
begin
  if not OpenDialog1.Execute then
    exit;
  FileName := OpenDialog1.FileName;
  mmInfo.Append('FileName = ' + FileName);
  mmInfo.Append('кодировка строки FileName = ' + IntToStr(StringCodePage(FileName)));
  mmInfo.Append('длина строки FileName = ' + IntToStr(Length(FileName)));
  if FileExists(FileName) then
    mmInfo.Append('FileExists(FileName) вернул True');
  FileName1251 := FileName;
  mmInfo.Append('FileName1251 = ' + FileName1251);
  mmInfo.Append('кодировка строки FileName1251 = ' + IntToStr(StringCodePage(FileName1251)));
  mmInfo.Append('длина строки FileName1251 = ' + IntToStr(Length(FileName1251)));
  if FileExists(FileName1251) then
    mmInfo.Append('FileExists(FileName1251) вернул True');
  mmInfo.Append('ExtractFileName(FileName) = ' + ExtractFileName(FileName));
  mmInfo.Append('ExtractFileName(FileName1251) = ' + ExtractFileName(FileName1251));
  with TStringList.Create do
    try
      LoadFromFile(FileName);
      mmInfo.Append('Текст файла: ' + LineEnding + Text);
    finally
      Free;
    end;
  CopyName := ExtractFileName(FileName);
  CopyName :=
    ExtractFilePath(FileName) + Copy(CopyName, 1, Pos('.', CopyName)-1) + '1' + ExtractFileExt(FileName);
  mmInfo.Append('CopyName = ' + CopyName);
  CopyFile(FileName, CopyName);
  if FileExists(CopyName) then
    mmInfo.Append('FileExists(CopyName) вернул True');

  with TStringList.Create do
    try
      LoadFromFile(CopyName);
      mmInfo.Append('Текст копии файла: ' + LineEnding + Text);
    finally
      Free;
    end;
end;

дает вот такой выхлоп:
Код: Выделить всё
FileName = D:\some files\Новая папка\кириллическая папка\Новый текстовый документ.txt
кодировка строки FileName = 65001
длина строки FileName = 124
FileExists(FileName) вернул True
FileName1251 = D:\some files\Новая папка\кириллическая папка\Новый текстовый документ.txt
кодировка строки FileName1251 = 1251
длина строки FileName1251 = 74
FileExists(FileName1251) вернул True
ExtractFileName(FileName) = Новый текстовый документ.txt
ExtractFileName(FileName1251) = Новый текстовый документ.txt
Текст файла:
строка 1
строка 2
строка 3

CopyName = D:\some files\Новая папка\кириллическая папка\Новый текстовый документ1.txt
FileExists(CopyName) вернул True
Текст копии файла:
строка 1
строка 2
строка 3
iskander
энтузиаст
 
Сообщения: 590
Зарегистрирован: 08.01.2012 18:43:34

Re: Логика работы UTF8ToSys/SysToUTF8

Сообщение wwswowsogon » 19.10.2019 09:48:02

Кстати, да, спасибо за напоминание, где-то вскользь слышал об этом. Сейчас используется 1.4. Пробовал 1.6, но там было всё ещё хуже с этим :)
Есть некий психологический барьер, но, пожалуй, надо попробовать, прогресс не остановить, you can't stop rock'n'roll :)
wwswowsogon
постоялец
 
Сообщения: 152
Зарегистрирован: 23.12.2008 20:41:37

Re: Логика работы UTF8ToSys/SysToUTF8

Сообщение Снег Север » 19.10.2019 09:58:38

wwswowsogon, вообще-то стандартный лазарь сейчас - 2.0.4 :D
Работает в utf8, для всяких FileExists есть utf8 эквиваленты в LazFileUtils, с которыми нет никаких этих ваших проблем.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2994
Зарегистрирован: 27.11.2007 16:14:47

Re: Логика работы UTF8ToSys/SysToUTF8

Сообщение zoltanleo » 21.10.2019 00:51:55

wwswowsogon писал(а): я хоть убей не могу понять, как же правильно применять перевод кодировок.

Правила просты: они применяются только для перевода анси-строк в utf8 и обратно, и только для винды. В основном, это строки, возвращаемые winapi.

В последних релизах 2.0.4/3.0.4 практически все конвертирующие функции упразднили за исключением WinCPToUTF8(и обратная этой).
Аватара пользователя
zoltanleo
постоялец
 
Сообщения: 457
Зарегистрирован: 17.10.2013 10:55:01


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Alex2013 и гости: 19

Рейтинг@Mail.ru