使用filesystem::path,如何以跨平台方式打开文件?

Using a filesystem::path, how do you open a file in a cross-platform way?

假设您使用了新的 std::filesystem(或 std::experimental::filesystem)代码来搜索文件。您有一个 path 变量,其中包含该变量的完整路径名。

你如何打开那个文件?

这听起来可能很傻,但考虑一下显而易见的答案:

std::filesystem::path my_path = ...;
std::ifstream stream(my_path.c_str(), std::ios::binary);

不能保证工作。为什么?因为例如 Windows,path::string_typestd::wstring。所以path::c_str会return一个const wchar_t*std::ifstream 只能 采用 const char* 类型的路径。

现在证明这段代码在 VS 中确实可以运行。为什么?因为Visual Studio有个library extension that does permit this to work。但这是非标准行为,因此不是 可移植的。例如,我不知道 Windows 上的 GCC 是否提供相同的功能。

你可以试试这个:

std::filesystem::path my_path = ...;
std::ifstream stream(my_path.string().c_str(), std::ios::binary);

只有Windows又把我们搞糊涂了。因为如果 my_path 恰好包含 Unicode 字符,那么现在您需要正确设置 Windows ANSI 语言环境。如果路径恰好包含来自同一 ANSI 区域设置中不能存在的多种语言的字符,即使这样也不一定能救你。

Boost Filesystem 其实也有类似的问题。但是他们扩展了他们的 iostreams 版本以直接支持 paths。

我是不是漏掉了什么?委员会是否添加了跨平台文件系统库,但没有添加跨平台方式来 open 中的文件?

Bo Persson指出这是一个standard library defect report的主题。此缺陷已解决,C++17 将发布,要求实现 path::value_type 不是 char 的文件流类型除了通常的 [=13] 外还采用 const filesystem path::value_type*s =] 版本。