【发布时间】: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