You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用std::filesystem递归遍历目录时遇Unicode转换异常1113的问询

解决std::filesystem::recursive_directory_iterator遍历含特殊Unicode字符文件的异常问题

问题现象

  • 使用std::filesystem::recursive_directory_iterator遍历目录时触发异常,设置directory_options::skip_permission_denied无法解决
  • 删除当前触发异常的文件后,异常会随机出现在其他文件;不删除该文件则每次遍历都会在该文件处触发
  • 在Visual Studio中点击三次继续按钮后,程序可恢复遍历

测试代码(简化后):

#define NOMINMAX

#include <string>
#include <iostream>
#include <filesystem>
#include <windows.h>
#include <fstream>
#include <winbase.h>
#include <numeric>
#include <string_view>
#include <vector>
#include <shlobj_core.h>
//#include <combaseapi.h>

namespace fs = std::filesystem;

using namespace std;

void startWinXSearch(string argv)
{
    string pathToFolder = argv;

    cout << pathToFolder << endl;

    for (auto& el : std::filesystem::recursive_directory_iterator(pathToFolder, std::filesystem::directory_options::skip_permission_denied)) {
        cout << el << endl;
    }
}

int main(int argc, char* argv[])
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);

    string test = "C:\\Sciebo";

    startWinXSearch(test);
}

排查过程

改用wcout输出后,得到明确错误信息:"No mapping for the Unicode character exists in the target multi-byte code page",最终定位到异常原因是目录中存在来自手机的文件,文件名包含无法映射到当前系统多字节代码页的隐形Unicode字符。

解决方案/规避方案

1. 全链路使用宽字符支持Unicode

将代码中的std::string替换为std::wstring,cout替换为wcout,确保路径处理和输出都支持完整Unicode字符集:

#define NOMINMAX

#include <wstring>
#include <iostream>
#include <filesystem>
#include <windows.h>
#include <fstream>
#include <winbase.h>
#include <numeric>
#include <string_view>
#include <vector>
#include <shlobj_core.h>

namespace fs = std::filesystem;

using namespace std;

void startWinXSearch(wstring argv)
{
    wstring pathToFolder = argv;

    wcout << pathToFolder << endl;

    for (auto& el : std::filesystem::recursive_directory_iterator(pathToFolder, std::filesystem::directory_options::skip_permission_denied)) {
        wcout << el.path() << endl;
    }
}

int main(int argc, char* argv[])
{
    CoInitializeEx(NULL, COINIT_MULTITHREADED);

    wstring test = L"C:\\Sciebo";

    startWinXSearch(test);
}

2. 捕获编码异常并跳过

在遍历和输出过程中添加异常捕获,针对编码相关错误直接跳过,保证遍历流程不中断:

void startWinXSearch(wstring argv)
{
    wstring pathToFolder = argv;

    wcout << pathToFolder << endl;

    try {
        for (auto& el : std::filesystem::recursive_directory_iterator(pathToFolder, std::filesystem::directory_options::skip_permission_denied)) {
            try {
                wcout << el.path() << endl;
            } catch (const std::exception& e) {
                wcerr << L"输出文件路径失败: " << e.what() << endl;
                continue; // 跳过该文件,继续遍历
            }
        }
    } catch (const std::filesystem::filesystem_error& e) {
        wcerr << L"遍历目录失败: " << e.what() << endl;
    }
}

3. 清理特殊字符文件

手动排查或通过文件搜索工具找到来自手机同步的含隐形Unicode字符的文件,重命名为合法名称或直接删除,从根源消除异常触发点。

内容的提问来源于stack exchange,提问作者Gisbert12843

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:15:11