我正在开发一个库(pugixml),其中提供了使用窄字符C字符串加载/保存XML文档的文件API等功能:
bool load_file(const char* path);
bool save_file(const char* path);
目前路径是直接传递给 fopen
函数的,这意味着在 Linux/OSX 上,你可以传递一个 UTF-8 字符串来打开文件(或任何其他有效路径的字节序列),但在 Windows 上,你必须使用 Windows ANSI 编码 - UTF-8 不起作用。
默认情况下,文档数据使用 UTF-8 表示,因此,如果你有一个包含文件路径的 XML 文档,你将无法直接将从文档中检索到的路径传递给 load_file
函数 - 或者说,在 Windows 上这样做不起作用。该库提供了使用 wchar_t
的替代函数:
bool load_file(const wchar_t* path);
但是使用它们需要额外的工作来将UTF8编码为wchar_t。
另一种方法(被SQLite和GDAL使用 - 不确定是否还有其他C/C ++库这样做)涉及在Windows上将路径视为UTF-8(这将通过将其转换为UTF-16并使用类似_wfopen的感知函数来打开文件来实现)。
我可以看到不同的利弊,我不确定哪种权衡最好。
一方面,在所有平台上使用一致的编码肯定是好的。这意味着您可以使用从XML文档中提取的文件路径来打开其他XML文档。此外,如果使用库的应用程序采用UTF-8,则在库中打开XML文件时无需进行额外的转换。
另一方面,这意味着文件加载的行为不再与标准函数相同 - 因此,通过库访问文件不等同于通过标准fopen/std :: fstream访问文件。似乎虽然一些库采用UTF-8路径,但这基本上是一个不受欢迎的选择(这是真的吗?),因此,针对使用许多第三方库的应用程序,它可能会增加混淆而不是帮助开发人员。
例如,将argv[1]传递到load_file中当前适用于在Windows上使用系统区域设置编码的路径(例如,如果您使用俄语区域设置,则可以以此方式加载任何具有俄语名称的文件,但是您将无法加载具有日语字符的文件)。切换到UTF-8将意味着仅ASCII路径有效,除非您通过某种其他特定于Windows的方式检索命令行参数。
当然,这将对库的某些用户造成破坏性变化。
我有没有漏掉任何重要的观点?是否还有其他采用同样方法的库?对于C ++来说,是保持不一致的文件访问更好,还是追求统一的跨平台行为?
请注意,问题是关于打开文件的默认方式 - 当然,没有什么阻止我添加带_utf8后缀的另一对函数或以其他方式指示路径编码。
_wfopen
/std::ifstream(wchar_t *)
?生成的文件对象与非wchar
函数打开的对象相同。(2)您是否阅读过http://utf8everywhere.org,并且您是否同意其中的观点?(3)请参见https://dev59.com/02gu5IYBdhLWcg3wv5ca。 - nneonneo