当前位置: 首页 > article >正文

将路径转换为短路径形式(8.3格式)解决 `CFile::Open` 无法打开长路径问题

背景知识

在 Windows 中,默认情况下,文件路径长度的限制为 260 个字符MAX_PATH)。当路径长度超过该限制时,MFC 的 CFile::Open 方法会失败并返回 false,因为它不支持长路径(即使使用 \\?\ 前缀也不适用)。在这种情况下,可以利用 Windows 短路径名(8.3格式) 来绕过路径长度限制。


什么是短路径名(8.3 格式)?

短路径名(也称为 8.3 文件名 格式)是 Windows 为了兼容早期操作系统而保留的一种文件命名格式。它的特点是:

  • 文件名最多 8 个字符。
  • 扩展名最多 3 个字符。
  • 不支持空格和大部分特殊字符。
  • 例如(真实场景):
    原路径:C:\Users\shaofeng\AppData\Local\JPDFM\unziptemp\Project Outputs for 控制板-Y平台-米家LS-零火-轻触大板-竖款-2-4开(Mesh2.0)-V1.0\Project Outputs for 控制板-Y平台-米家LS-零火-轻触大板-竖款-2-4开(Mesh2.0)-V1.0\控制板-Y平台-米家LS-零火-轻触大板-竖款-2-4开(Mesh2.0)-V1.0-拼板.GBL (279个字符超过了260)
    短路径:C:\Users\shaofeng\AppData\Local\JPDFM\UNZIPT~1\PROJEC~1.0\PROJEC~1.0\控制板~1.GBL

Windows 会为大多数长路径自动生成对应的短路径名,这个短路径名通常比原路径短得多,可以绕过 MAX_PATH 的限制。


使用 GetShortPathName 函数

Windows 提供了 GetShortPathName API 来获取文件或目录的短路径形式。

函数原型
DWORD GetShortPathName(
    LPCTSTR lpszLongPath,  // 输入长路径
    LPTSTR lpszShortPath,  // 输出短路径
    DWORD cchBuffer        // 输出缓冲区的大小
);

参数说明:

  • lpszLongPath:指向长路径的字符串。
  • lpszShortPath:用于接收短路径的缓冲区。
  • cchBuffer:缓冲区大小。

返回值

  • 成功时,返回写入 lpszShortPath 的字符串长度。
  • 失败时,返回 0,可通过 GetLastError 获取错误代码。

实现步骤

  1. 调用 GetShortPathName 将长路径转换为短路径
  2. 使用 CFile::Open 打开转换后的短路径
  3. 进行文件读取或写入操作

代码示例

头文件包含
#include <afx.h>          // MFC 核心类
#include <shlwapi.h>      // Path 相关函数
#include <windows.h>      // Windows API
主代码
void OpenLongPathFile(CString longPath) {
    TCHAR shortPath[MAX_PATH] = {0};

    // 将长路径转换为短路径
    if (GetShortPathName(longPath, shortPath, MAX_PATH) == 0) {
        DWORD dwError = GetLastError();
        CString errorMsg;
        errorMsg.Format(_T("Failed to get short path name. Error code: %lu"), dwError);
        AfxMessageBox(errorMsg);
        return;
    }

    CString shortPathStr(shortPath);
    CFile file;

    // 尝试使用短路径打开文件
    try {
        if (file.Open(shortPathStr, CFile::modeRead)) {
            AfxMessageBox(_T("File opened successfully using short path."));
            // 读取文件内容(示例)
            char buffer[1024];
            UINT bytesRead = file.Read(buffer, sizeof(buffer));
            file.Close();
        } else {
            AfxMessageBox(_T("Failed to open file using short path."));
        }
    } catch (CFileException& e) {
        TCHAR szErr[1024];
        e.GetErrorMessage(szErr, 1024);
        CString errorMessage;
        errorMessage.Format(_T("Error opening file: %s\nError Message: %s"), shortPathStr, szErr);
        AfxMessageBox(errorMessage);
    }
}
调用示例
CString longFilePath = _T("C:\\Users\\shaofeng\\AppData\\Local\\JPDFM\\unziptemp\\Project Outputs for 控制板-Y平台-米家LS-零火-轻触大板-竖款-2-4开(Mesh2.0)-V1.0\\Project Outputs for 控制板-Y平台-米家LS-零火-轻触大板-竖款-2-4开(Mesh2.0)-V1.0\\控制板-Y平台-米家LS-零火-轻触大板-竖款-2-4开(Mesh2.0)-V1.0-拼板.GBL");
OpenLongPathFile(longFilePath);

总结

  1. 问题背景
    • MFC 的 CFile::Open 无法处理超过 260 个字符的路径(MAX_PATH 限制)。
    • 直接使用长路径会导致 CFile::Open 返回 false
  2. 解决方法
    • 使用 Windows 提供的 短路径名(8.3 格式) 来替代长路径。
    • 通过 GetShortPathName 将长路径转换为短路径,再用 CFile::Open 打开文件。
  3. 步骤总结
    1. 调用 GetShortPathName 将长路径转换为短路径。
    2. 使用转换后的短路径调用 CFile::Open
    3. 添加错误检查和异常处理,确保路径转换和文件打开成功。
  4. 优点
    • 兼容多字节字符集(MBCS)。
    • 无需更改项目的字符集设置。
    • 简单易用,适合大多数场景。

通过这种方法,你可以在 MFC 项目中成功打开超过 260 字符的路径文件。


http://www.kler.cn/a/430678.html

相关文章:

  • 最新的强大的文生视频模型Pyramid Flow 论文阅读及复现
  • Windows脚本命令与Linux Bash脚本命令
  • 【数据库原理】数据增删改查,DML、单表查询、多表连接查询
  • 778-批量删除指定文件夹下指定格式文件(包含子孙文件夹下的)
  • ArcGIS Pro 3.4新功能3:空间统计新特性,基于森林和增强分类与回归,过滤空间自相关
  • 我用Cursor+DeepSeek做了个飞书文档一键同步插件,免费使用!
  • 从零搭建网站(第三天)
  • 连续大涨,汉王科技跑步进入AI应用舒适区
  • Vue.js的生命周期
  • go使用闭包处理数据
  • List与Set、数组与ArrayList、ArrayList与LinkedList的区别
  • 【kafka】常用基础命令使用案例
  • ViT学习笔记(三) RepViT和TransNext简介
  • 【定时任务】定时任务技术实现原理和选型分析
  • 分析比对vuex和store模式
  • vue-生命周期
  • 力扣 螺旋矩阵-54
  • vscode 配置C/C++环境控制台参数
  • 【FLASH、SRAM和DRAM、CISC和RISC、冯诺依曼和哈佛】单片机内存结构的了解
  • 网页核心页面设计(第5章)
  • 给我的小程序加了个丝滑的搜索功能,踩坑表情包长度问题
  • Win11家庭版安装Docker,解决engine stopped问题
  • 初始数据结构
  • 电脑文件夹打不开了,能打开但是会闪退,提示“找不到iUtils.dll”是什么原因?
  • 电脑运行时提示“0x80240037”错误,提示安装ie插件或其他微软程序时,报错提示“未指定的错误”是什么原因?以及要怎么解决和预防?
  • AUTOSAR AP和CP的安全要求规范(Safety Req)详细解读