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

标签 c++ c++17

假设您使用了新的 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 将返回一个 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。

我在这里遗漏了什么吗?委员会是否添加了跨平台文件系统库而不添加跨平台方式来打开其中的文件?

最佳答案

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

关于c++ - 使用 filesystem::path,如何以跨平台方式打开文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38124415/

相关文章:

c++ - 将 smart_pointer 传递给构造函数与原始指针

c++ - 请帮助我使用 C++ 命名空间

c++ - C++ 中的前向声明模板变量

c++ - 为什么 `std::all_of` 不使用 `std::invoke` ?

c++ - CListCtrl选择

c++ - 比较 std::wstring 和 std::string

c++ - Boost 能做什么而现代 C++ 不能?

c++ - 在 lambda 中捕获的 constexpr 变量失去了它的 constexpr-ness

c++ - 为什么 std::iota 不是 constexpr?

c++ - 完美转发常量参数以进行持续评估