boost::iostreams::mapped_file_source 打开具有 CJK 文件名的文件

boost::iostreams::mapped_file_source opens a file that has CJK filename

假设我们有这样的代码:

boost::iostreams::mapped_file_source dev(paFileName.u8string().c_str());

其中 paFileName 是一个 std::filesystem::path 对象。

在Windows上,std::filesystem::path中的内部字符是wchar_t,但boost::iostreams::mapped_file_source似乎只接受变宽字符串。因此,我们使用方法 u8string.

将固定宽度 wchar_t 字符串转换为可变宽度 char 字符串

问题是转换显然导致 boost::iostreams::mapped_file_source 的 ctor 无法在文件系统中找到文件,并且 ctor 将抛出一个 boost::wrapexcept<std::ios_base::failure[abi:cxx11]>,上面写着“打开文件失败:系统找不到指定的文件。"

如何解决这个问题?有什么建议么?谢谢。

根据compile-time错误的提示:

C:/msys64/mingw64/include/boost/iostreams/detail/path.hpp:138:5: note: declared private here
  138 |     path(const std::wstring&);
      |     ^~~~

不知何故 Boost.Iostreams 试图将 std::filesystem::path 转换为 boost::iostreams::details::path 但失败了,因为接受宽字符串的转换 ctor 不可访问。 Linux 上不会出现此问题,因为 Linux 上的文件系统通常使用 UTF-8 char 字符串作为文件名。相反,在 Windows 上,文件名通常是 UTF-16 wchar_t 字符串。

我的解决方法是避免调用上面提到的转换构造函数。我给了一个boost::filesystem::wpath而不是原来的std::filesystem::path给Boost.Iostreams,希望Boost版本wpath更容易被Boost.Iostreams接受。

boost::iostreams::stream<boost::iostreams::mapped_file_source> fin(
    boost::filesystem::wpath(static_cast<std::wstring>(paFileName))
);

而且有效。