【问题标题】:MinGW C++: Reading a file with non-ascii file nameMinGW C++:读取具有非 ascii 文件名的文件
【发布时间】:2016-09-20 12:45:27
【问题描述】:

简单任务:我想读取一个非 ascii 文件名的文件。

在 linux 和 MacOS 上,我只是将文件名作为 UTF-8 编码字符串传递给 fstream 构造函数。在 Windows 上,这会失败。

我从this question 了解到,Windows 根本不支持 utf-8 文件名。但是,它提供了一个自己的非标准 open 方法,该方法采用 utf-16 wchar_t*。因此,我可以简单地将我的 string 转换为 utf-16 wstring 就可以了。但是在MinGW标准库中,fstream的那个wchar_t* open方法根本就不存在。

那么,如何在 MinGW 上打开非 ASCII 文件名?

【问题讨论】:

标签: c++ windows unicode mingw fstream


【解决方案1】:

我以前也遇到过同样的问题。不幸的是,在您可以使用 std::filesystem::path 之前,您需要以某种方式解决这个问题,例如通过包装一切,例如就像我做的here,这使得“用户代码”看起来像这样:

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++ 上不起作用,尽管该组合目前无论如何都不起作用,这并不重要。

【讨论】:

  • std::filesystem::path 的解决方案是什么样的?那个类不是已经可以作为实验扩展了吗?
  • 它在最新版本中。我相信 MSVC 也支持某种形式的文件系统,不知道它们是否兼容。除了technical specification,我找不到任何东西,这似乎意味着如果我正确阅读它,Windows 将保持完全崩溃:/。
【解决方案2】:

你或许可以试试Boost.Nowide。它有一个fstream 包装器,它会自动将您的字符串转换为 UTF-16。它还没有在 boost 中,但已经在 review schedule 中(希望很快成为 boost 的一部分)。我从来没有用 mingw 尝试过,但是用 Visual Studio 玩了一下,发现它很整洁。

【讨论】:

  • 如果我在我们的项目中引入这样一个尚不稳定的依赖项,我的经理会杀了我;)。
  • @gexicide 我看到了.... 可能比更专业的图书馆icu。但我从未尝试过,所以我不能说它是否符合您的要求。
  • ICU 有办法从 UTF-16 对象打开 fstream 吗?我们已经使用了 ICU,但仅仅转换为 UTF-16 是不够的,因为我想念接受它的 fstream 构造函数。
  • @gexicide 嗯……这很奇怪。我认为将字符串转换为 UTF-16,将其放入宽字符字符串变体并使用宽字符变体 std::wifstream 可以工作。但是,正如我所说,我从未尝试过,因为我尽量避免使用任何 Widechar/UTF-16 内容,并尝试仅使用 UTF-8。
  • 不,它没有:)。我不想要wifstreamwifstream 假定 文件内容 是多字节字符。但事实并非如此,只有 文件名 是 unicode。因此wifstream 的构造函数也采用char,而不是wchar_t。没有 wchar_t 构造函数 - 至少在 MinGW 或 linux 上没有。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 2013-10-09
相关资源
最近更新 更多