如何让 C++ wfstream 使用 Unicode 文件路径?

问题描述

我有一个应用程序使用 utf-8 编码的宽字符串处理文件 I/O

工作代码

const wchar_t* wc = L"C:\Documents\TestPath\TestFile.txt";
std::wfstream wf(wc);
wf.imbue(std::locale(wf.getloc(),new std::codecvt_utf8<wchar_t,0x10ffff,std::consume_header>()));
return wf.is_open();
...
wf << L"測試文件夾" << L"\n";

但是,一旦在文件路径中引入了 unicode 字符,文件将无法正常打开。 IE。以下代码不起作用并返回false:

const wchar_t* wc = L"C:\Documents\測試文件夾\TestFile.txt";
std::wfstream wf(wc);
return wf.is_open();

在这里做错了什么?似乎应该有一种简单的方法可以让 wfstream 使用 unicode 文件路径,但我已经在互联网上搜索了所有内容,但找不到。

谢谢

解决方法

感谢大家的帮助。

我发现了如何让代码使用一个不寻常的解决方案,这可能会对处于相同情况的其他人有所帮助:

  1. 使用 C 风格的 _wfopen 创建文件
FILE * fp = _wfopen(cpFullPath,L"w"); 
fclose(fp); 
  1. 使用 ::GetShortPathW 函数获取新创建文件的 UTF8 路径的简短 ASCII 表示
wchar_t short_path[511] {} ;                                                
::GetShortPathNameW( cpFullPath,short_path,511 ) ;
// cpFullPath is L"C:\\Desktop\\測試文件夾\\те \x81това \x8f папка\\file.txt" 
// short_path becomes L"C:\\Desktop\\12BE~3\\81C2~6\\file.txt"      
  1. 使用 wfstream 打开文件并为 UTF8 I/O 注入流
std::wfstream textFileStream;
textFileStream.open(short_path,ios::in | ios::out);
textFileStream.imbue(std::locale(textFileStream.getloc(),new std::codecvt_utf8<wchar_t,0x10ffff,std::consume_header>())); 
,

您的字符串文字需要转义 \ 个字符,例如:

const wchar_t* wc = L"C:\\Documents\\TestPath\\TestFile.txt";
const wchar_t* wc = L"C:\\Documents\\測試文件夾\\TestFile.txt";

否则,请改用原始字符串文字:

const wchar_t* wc = LR"(C:\Documents\TestPath\TestFile.txt)";
const wchar_t* wc = LR"(C:\Documents\測試文件夾\TestFile.txt)";

话虽如此,请仔细检查用于保存 cpp 文件的字符集是否与编译器用于解析文件的字符集匹配,否则像 測試文件夾 这样的非 ASCII 字符将无法在字符串文字中正确工作。

否则,请改用 Unicode 转义序列:

const wchar_t* wc = L"C:\\Documents\\\u6e2c\u8a66\u6587\u4ef6\u593e\\TestFile.txt";