我正在编写一个针对Windows XP / 7/10的Lazarus(1.5)fpc(3.1.1)应用程序。 我的应用程序在用户选择的某个路径中读取和写入文件系统中的文件。如果路径或文件名包含特殊字符(例如àèé),例如:
C:\用户\德安德鲁\ out.txt
应用程序引发异常:
'EFCreateError'无法创建文件“C:\ Users \DeAndrè\ out.txt”。
可以使用sigle格式编写一个简单的应用程序来重现此问题: 拖入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 FileSystem不是UTF8?
有“标准”解决方案吗?例如,将应用程序设置为以正确模式或类似方式使用文件系统?
谢谢
答案 0 :(得分:1)
在Rudy和David的指示后我找到了解决方案: 要使Lazarus能够使用UnicodeAPI,您必须在"自定义选项"上添加 -dEnableUTF8RTL :
On" Project" - >" Project Options" - >" Additions and Override"
点击"添加" - >"自定义选项"并添加
-dEnableUTF8RTL
此强制编译器将Unicode用于FileSystem Access。
也可以点击按钮"在RTL"中设置UTF8。 除了-dEnableUTF8RTL之外,此按钮还添加了选项:
-FcUTF8
在拉撒路论坛的这个链接中: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用户现在可以在中使用UTF-8字符串 RTL。