C++ WinAPI:处理长文件路径/名称

Posted

技术标签:

【中文标题】C++ WinAPI:处理长文件路径/名称【英文标题】:C++ WinAPI: handling long file paths/names 【发布时间】:2011-03-17 16:52:45 【问题描述】:

我正在考虑在我的 Windows 应用程序中处理更长的文件路径。

目前,我有一个文本框(编辑框),用户可以在其中键入绝对文件路径。然后,我使用GetWindowText 将键入的文件路径读入一个声明为这样的字符串:TCHAR FilePath[MAX_PATH];

显然,我在这里依赖 MAX_PATH 常量,它将我限制为 260 个字符。因此,要处理更长的文件/路径名称,我可以像这样扩展我的 TCHAR 数组:TCHAR FilePath[32767];

或者有更好的方法吗?我可以使用可变长度数组吗? (TCHAR FilePath[]; 这在 C++ 中是否可行? - 抱歉,我对此很陌生)。

谢谢你!


这是我上面提到的整个代码sn-p:

TCHAR FilePath[MAX_PATH];
ZeroMemory(&FilePath, sizeof(FilePath));
GetWindowText(hWndFilePath, FilePath, MAX_PATH);

【问题讨论】:

这正是MAX_PATH 的目的——你不能有比这更长的路径。 @casablanca 不过,最好使用 MAX_PATH+1 声明最后一个 '\0' 字符。 @luiscabal:我刚刚检查了MSDN,看起来 MAX_PATH 包含空终止符。 【参考方案1】:

Windows 上的文件路径存在许多限制。默认情况下,路径不能超过 260 个字符,这就是 MAX_PATH 常量的用途。

但是,您可以访问更长的路径 - 有一定的限制 - 通过在路径前加上“\\?\”前缀。但是,使用“\\?\”前缀的局限性通常大于好处:

    许多 Win32 API 不支持带有此前缀的路径(例如,LoadLibrary 在长度超过 260 个字符的路径上总是会失败) 使用“\\?\”前缀时,Win32 规范化规则不生效。例如,默认情况下,路径中的“/”会转换为“\”、“.”。和 ".." 分别转换为对当前目录和父目录的引用,依此类推:当您使用 "\\?\" 前缀时,这些都不会发生。 仅仅因为您可以修改您的 程序以支持更长的路径,其他程序可能无法打开您创建的文件。如果其他程序不使用“\\?\”前缀,就会出现这种情况。

老实说,第 2 点才是真正的杀手:使用“\\?\”前缀时,您会遇到各种麻烦,而且您基本上必须自己重新实现 Win32 规范化规则那条路线。

因此,我的建议是坚持 260 限制。至少在为更长的路径提供更好的平台支持之前。

【讨论】:

感谢您的建议。我想我会听从你的建议! 对于#2,请注意GetFullPathNameW 为您执行此规范化,并且限制为 MAX_PATH,除非您将其指定为缓冲区大小。 (仅在调用 GetFullPathName 之后 为路径添加前缀 \\?\。)一些剩余的注意事项:1) UNC 路径必须使用 \\?\UNC\ 代替 \\。 2) NUL 或 somedir\NUL 等 DOS 设备被转换为 \\.\NUL,但 \\.\ 并非在任何地方都有效(而 \\?\UNC\.\NUL 完全是另外一回事)。 3) \\?\C:\NUL 可以创建一个难以处理的文件。【参考方案2】:

这取决于您编写的程序类型。我自己的策略通常是将路径 creation 的长度限制为 MAX_PATH,但能够从较长的路径中读取 existing 数据(使用“\\?\”前缀 Dean在他的回答中提到)。不过也有例外——例如,备份程序应该接受长路径,并且必须准确地再现它作为输入给出的内容。

虽然 Dean 认为 Windows 不会为您规范化更长的路径当然是正确的,但我没有发现这作为一般规则非常值得关注。这通常也不意味着编写您自己的代码来规范化路径 - 它通常意味着让用户以一种根本不首先生成此类内容的方式输入路径。

【讨论】:

【参考方案3】:

不,因为如果您获得更长的路径,Windows 将无法接受。因此,虽然从技术上讲,您可以在缓冲区中保存更多的字符,但您永远无法真正使用文件路径结果。

【讨论】:

以上是关于C++ WinAPI:处理长文件路径/名称的主要内容,如果未能解决你的问题,请参考以下文章

使用 robocopy 复制文件(长名称和路径,以及许多空格) - 缺少参数

windows路径太长无法删除

使用长文件路径时的 Get-ChildItem 错误处理

windows路径太长无法删除

如何删除一个无限长路径的文件夹(别说robocopy、金山粉碎机啥的 用过无效)解决追加100+

无法使用 Python 在 Windows 上找到具有长名称的文件