简单的任务:我想读取一个非ascii文件名的文件。
在 Linux 和 MacOS 上,我只需将文件名作为 UTF-8 编码字符串传递给
fstream
构造函数。在 Windows 上这会失败。
正如我从这个问题中了解到的那样,Windows根本不支持utf-8文件名。但是,它提供了一个自己的非标准
open
方法,该方法采用 utf-16 wchar_t*
。因此,我可以简单地将我的 string
转换为 utf-16 wstring
就可以了。然而,在 MinGW 标准库中,wchar_t* open
的 fstream
方法根本不存在。
那么,如何在 MinGW 上打开非 ASCII 文件名?
我之前也遇到过同样的问题。不幸的是,在您可以使用
std::filesystem::path
之前,您需要以某种方式解决这个问题,例如通过包裹一切,例如 就像我在这里所做的那样,这使得“用户代码”看起来像这样:
auto stream_ptr = open_ifstream(file_name); // I used UTF-8 and converted to UTF-16 on Windows as in the code linked above
auto& stream = *stream_ptr;
if(!stream)
throw error("Failed to open file: \'" + filename + "\'.");
丑陋是的,稍微便携,是的。请注意,这在 Windows 上的 Libc++ 上不起作用,尽管该组合当前无论如何都不起作用,但这并不重要。
您或许可以尝试一下 Boost.Nowide。它有一个
fstream
包装器,可以自动将字符串转换为 UTF-16。它尚未进入 boost,但已经在审查时间表中(希望很快成为 boost 的一部分)。我从来没有用 mingw 尝试过,但是用 Visual Studio 玩了一下,发现它很简洁。
我通过将 UTF8 std::string 转换为 std::filesystem::path 然后将其发送到 std::ifstream 构造函数(Windows 10、MSYS2、GCC、C++17)解决了这个问题:
std::filesystem::path xpath(file_name);
std::ifstream xstream(xpath);
适用于 file_name 字符串中的非 ASCII 字符。