【问题标题】:Lazarus ListBox SaveToFile File Name with special charactersLazarus ListBox SaveToFile 带有特殊字符的文件名
【发布时间】:2017-05-17 12:09:49
【问题描述】:

我正在编写一个针对 Windows XP/7/10 的 Lazarus (1.5) fpc (3.1.1) 应用程序。 我的应用程序在用户选择的某些路径中读取和写入文件系统中的文件。如果路径或文件名包含特殊字符(如 à è é),例如:

C:\Users\DeAndrè\out.txt

应用程序引发异常:

'EFCreateError' 无法创建文件“C:\Users\DeAndrè\out.txt”。

是否可以使用单一表单编写一个简单的应用程序来重现此问题: 拖入窗体一个TListBox(ListBox1),两个TButton(Button1和Button2)和一个TSaveDialog(SaveDialog1)。

在Button1的OnClick事件中(仅用于在ListBox1上写入一些数据):

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Simple Add Hello to ListBox
  ListBox1.Items.Add('Hello '+IntToStr(ListBox1.Items.Count));
end; 

在 Button2 的 OnClick 事件中:

procedure TForm1.Button2Click(Sender: TObject);
begin
  if SaveDialog1.Execute then
  begin
    ListBox1.Items.SaveToFile(SaveDialog1.FileName);
  end;
end;  

运行应用程序并单击“Button1”几次(仅用于在列表中添加一些单词)然后单击 Button2 并尝试将内容保存到包含特殊字符的路径...

我注意到,如果我用函数 UTF8ToAnsi 转换 FileName 就可以了,但是为什么呢? Windows 文件系统不是 UTF8?

有“标准”解决方案吗?例如将应用程序设置为以正确模式或类似模式使用文件系统?

谢谢

【问题讨论】:

  • @RudyVelthuis 谢谢,我的 Windows 安装使用 NTFS 文件系统,根据this link 是 Unicode
  • 是lazarus代码调用Unicode API
  • 对不起,评论没有写完。忘掉它。我敢打赌 Lazarus(默认情况下)使用 ANSI API,而不是 Unicode API。 Delphi XE8 默认使用 UnicodeString,而 Lazarus 默认使用(旧式)AnsiString,AFAIK。
  • Windows API 实际上使用 ANSI 或 UTF-16,而不是 UTF-8。我想至少在 Windows 上也可以选择使用 UTF-16。但是默认情况下,调用的 API 也必须是 UTF-16。否则,您仍然需要为每个 API 调用进行转换。
  • @Rudy Lazarus 库可以在调用任何 API 之前从 UTF8 转换为 UTF16。那是完全合理的。

标签: windows filesystems filenames lazarus


【解决方案1】:

在 Rudy 和 David 的指导下,我找到了解决方案: 要让 Lazarus 使用 UnicodeAPI,您必须在“自定义选项”上添加 -dEnableUTF8RTL

在“项目”->“项目选项”->“添加和覆盖”

点击“添加”->“自定义选项”并添加

-dEnableUTF8RTL

这强制编译器使用 Unicode 进行文件系统访问。

也可以单击“在 RTL 中设置 UTF8”按钮。 这个按钮除了 -dEnableUTF8RTL 外还添加了选项:

-FcUTF8

在 Lazarus 论坛的这个链接中:http://forum.lazarus.freepascal.org/index.php?topic=27240.0 “Wiki”页面中有一段关于 Lazarus 和 UTF8 的摘录:

通常 RTL 将系统代码页用于字符串(例如 FileExists 和 TStringList.LoadFromFile)。在 Windows 上,这是一个非 Unicode 编码,因此您只能使用您的语言组中的字符。这 LCL 使用 UTF-8 编码,这是完整的 Unicode 范围。在 Linux 和 Mac OS X UTF-8 通常是系统代码页,因此 RTL 这里默认使用 CP_UTF8。

从 FPC 2.7.1 开始,可以更改 RTL 的默认系统代码页 转为 UTF-8 (CP_UTF8)。所以 Windows 用户现在可以在 右转。

【讨论】:

  • 您可以接受自己的答案(发布两天后),这将有助于以后的其他人,
猜你喜欢
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多