没有广泛 API 的可移植 UTF-8 接口(Windows 和 Unix)

Posted

技术标签:

【中文标题】没有广泛 API 的可移植 UTF-8 接口(Windows 和 Unix)【英文标题】:Portable UTF-8 Interface (Windows and Unix) without wide API 【发布时间】:2015-05-26 09:46:10 【问题描述】:

我正在使用以下界面设置硬盘驱动器上文件的路径:

void setPath(const char* path);

此路径将用于基本文件 I/O。

例如,如果我提供一个包含中文字符的路径(例如,通过 QString::toUtf8()),这对 Unix 工作正常,但对于 Windows 当然不是,因为内部使用了 wchar/wstring API。

我现在正在寻找一种优雅的方式来使这个接口在基于 Windows 和 Unix 的系统上兼容 UTF-8。 有没有办法避免在基于 Windows 的系统上使用宽 API 并继续使用 std::string 和 std::ofstream() ?

在查看 boost::locale 之后,我觉得这可以处理 UTF-8 编码。这会是一种方法吗(例如,用它的 boost::ofstream() 对应物替换 std::ofstream ?)

const std::locale loc = generator.generate(std::locale(), "zh_CN.UTF-8");
std::locale::global(loc);
std::cout.imbue(std::locale());
boost::filesystem::path::imbue(std::locale())

感谢所有帮助。

【问题讨论】:

【参考方案1】:

有没有办法避免在基于 Windows 的系统上使用宽 API

Windows API 不支持 UTF-8,除了少数选定的 API。很大程度上它只支持依赖于语言环境的 ANSI 和 UTF-16。要在不丢失数据的情况下支持 Unicode,您必须使用基于 UTF-16 的 API。

在将 UTF-8 字符串传递给 Windows API 函数时,您的接口需要在内部将其转换为 UTF-16,并在从 API 接收数据时将其从 UTF-16 转换为 UTF-8。没有其他办法。这属于您的底层平台特定逻辑,而不是更高层的公共接口。

并继续使用 std::string 和 std::ofstream() ?

您可以将std::string 用于UTF-8,并且有很多方法可以在std::string UTF-8 和std::wstring UTF-16 之间进行转换(C++11 中甚至还有类来处理它) .

Microsoft 在 Visual Studio 中对 std::ifstreamstd::ofstream 进行了非标准扩展,以接受 UTF-16 文件名。其他供应商可能会也可能不会提供类似的功能。

【讨论】:

以上是关于没有广泛 API 的可移植 UTF-8 接口(Windows 和 Unix)的主要内容,如果未能解决你的问题,请参考以下文章

库如何实现不同操作系统之间的可移植性

有没有办法使用 Django REST 框架中的可浏览 API 上传文件?

C++的可移植性和跨平台开发

Python基础Web服务器案例

Java并发编程(06):Lock机制下API用法详解

Java Swing 应用程序到 OSX 的可移植性