gpt4 book ai didi

c++ - 使用纯 C++/Boost 读取/写入具有 unicode 文件名的文件

转载 作者:可可西里 更新时间:2023-11-01 15:48:51 25 4
gpt4 key购买 nike

我想使用 boost 文件系统读取/写入具有 unicode 文件名的文件,Windows 上的 boost 语言环境(mingw)(最后应该是平台独立的)。

这是我的代码:

#include <boost/locale.hpp>
#define BOOST_NO_CXX11_SCOPED_ENUMS
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
namespace fs = boost::filesystem;

#include <string>
#include <iostream>

int main() {

std::locale::global(boost::locale::generator().generate(""));
fs::path::imbue(std::locale());

fs::path file("äöü.txt");
if (!fs::exists(file)) {
std::cout << "File does not exist" << std::endl;
}

fs::ofstream(file, std::ios_base::app) << "Test" << std::endl;
}

fs::exists 确实会检查名称为 äöü.txt 的文件。但是写入的文件名为 äã¶Ã¼.txt

阅读给出同样的问题。使用 fs::wofstream 也无济于事,因为它只能处理宽输入。

如何使用 C++11 和 boost 解决这个问题?

编辑: 发布错误报告:https://svn.boost.org/trac/boost/ticket/9968

澄清悬赏:使用 Qt 非常简单,但我想要一个仅使用 C++11 和 Boost 的跨平台解决方案,没有 Qt 也没有 ICU。

最佳答案

这可能很复杂,原因有二:

  1. 您的 C++ 源文件中有一个非 ASCII 字符串。此文字如何转换为 const char * 的二进制表示形式取决于编译器设置和/或操作系统代码页设置。

  2. Windows 仅通过 UTF-16 编码处理 Unicode 文件名,而 Unix 使用 UTF-8 编码 Unicode 文件名。

构造路径对象

要使其在 Windows 上运行,您可以尝试将文字更改为宽字符 (UTF-16):

const wchar_t *name = L"\u00E4\u00F6\u00FC.txt";
fs::path file(name);

要获得完整的跨平台解决方案,您必须从 UTF-8 或 UTF-16 字符串开始,然后确保它正确转换为 path::string_type 类。

打开文件流

不幸的是,C++(以及 Boost)ofstream API 不允许指定 wchar_t 字符串作为文件名。 constructor 都是这种情况。和 open method .

您可以尝试确保路径对象不会立即转换为 const char *(通过使用 C++11 字符串 API),但这可能无济于事:

std::ofstream(file.native()) << "Test" << std::endl;

要使 Windows 正常工作,您可能必须调用支持 Unicode 的 Windows API,CreateFileW ,将 HANDLE 转换为 FILE *,然后将 FILE * 用于 ofstream 构造函数。这就是全部described in another StackOverflow answer ,但我不确定 MinGW 上是否存在 ofstream 构造函数。

不幸的是 basic_ofstream 似乎不允许自定义 basic_filebuf 类型的子类化,所以 FILE * 转换可能是唯一的(完全非-可移植)选项。

替代方案:内存映射文件

除了使用文件流,您还可以使用 memory-mapped I/O 写入文件.根据 Boost 如何实现它(它不是 C++ 标准库的一部分),这种方法可以使用 Windows Unicode 文件名。

这是一个使用 path 对象打开文件的 boost 示例(取自 another answer):

#include <boost/filesystem.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#include <iostream>

int main()
{
boost::filesystem::path p(L"b.cpp");
boost::iostreams::mapped_file file(p); // or mapped_file_source
std::cout << file.data() << std::endl;
}

关于c++ - 使用纯 C++/Boost 读取/写入具有 unicode 文件名的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23393870/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com