我应该处理超过MAX_PATH的文件吗?

Joh*_*ohn 30 winapi max-path

刚做了一个有趣的案例.

我的软件报告了由于路径长于MAX_PATH而导致的故障.

该路径只是我的文档中的一个普通旧文档,例如:

C:\Documents and Settings\Bill\Some Stupid FOlder Name\A really ridiculously long file thats really very very very..........very long.pdf
Run Code Online (Sandbox Code Playgroud)

总长度为269个字符(MAX_PATH == 260).

用户没有使用外部硬盘或类似的东西.这是Windows托管驱动器上的文件.

所以我的问题是这个.我应该关心吗?

我不是说可以我对付长的路径,我问应该 I.是的,我知道一些的Win32 API的"\?\"的Unicode劈,但似乎这个技巧是不是没有风险(如它正在改变API解析路径的行为方式),并且所有API都不支持.

所以,无论如何,让我只说出我的立场/断言:

  1. 首先可能是用户能够打破此限制的唯一方法是,如果她使用的应用程序使用特殊的Unicode黑客攻击.这是一个PDF文件,所以她使用的PDF工具可能使用这个hack.
  2. 我尝试重现这个(通过使用unicode hack)并进行实验.我发现虽然文件出现在资源管理器中,但我无能为力.我无法打开它,我无法选择"属性"(Windows 7).其他常见的应用程序无法打开文件(例如IE,Firefox,记事本).资源管理器也不会让我创建太长的文件/目录 - 它只是拒绝.同上命令行工具cmd.exe.

基本上,人们可以这样看待它:一个胭脂工具允许用户创建一个许多Windows无法访问的文件(例如Explorer).我可以认为我不应该处理这个问题.

(顺便说一下,这不是对最短路径长度的批准投票:我认为260个字符是一个笑话,我只是说如果Windows shell和一些API无法处理> 260那么我为什么要这样做?).

那么,这是一个公平的观点吗?我应该说"不是我的问题"吗?

更新:刚刚让另一个用户遇到同样的问题.这次是一个mp3文件.我错过了什么吗?这些用户如何创建违反MAX_PATH规则的文件?

Ole*_*leg 12

这不是一个真正的问题.NTFS支持最大32K(32,767个宽字符)的文件名.您只需使用正确的API和正确的文件名语法.基本规则是:文件名应该以'\\?\'(例如http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx)开头\\?\C:\Temp.您可以使用与UNC相同的语法:\\?\UNC\Server\share\Path.重要的是要了解您只能使用一小部分API函数.例如,查看MSDN函数描述

CreateFile
CreateDirectory 
MoveFile
Run Code Online (Sandbox Code Playgroud)

等等

你会发现像这样的文字:

在此函数的ANSI版本中,名称仅限于MAX_PATH字符.要将此限制扩展为32,767个宽字符,请调用该函数的Unicode版本并在路径前添加"\?\".有关更多信息,请参阅命名文件.

这个功能可以安全使用.如果你有一个文件句柄从CreateFile您可以使用使用的所有其他功能hFile(ReadFile,WriteFile等等),没有任何限制.

如果你编写一个程序,如病毒扫描程序或备份软件或在服务器上运行的一些好的软件,你应该编写你的程序,所有文件操作支持最多32K字符而不是MAX_PATH字符的文件名.

  • @约翰.你误解了"\\?\"的工作方式.这不是**一个黑客!有很好的文档记录方式主要直接使用Native Windows NT API(来自ntdll.dll),如NtCreateFile http://msdn.microsoft.com/en-us/library/bb432380%28VS.85%29.aspx.如果您使用此功能,您将获得**不低于安全性,但只会减少安慰**.大多数Windows API都来自16位Windows 3.0,并且具有MAX_PATH限制.Native Windows NT API(来自ntdll.dll)主要用于驱动程序编程.所以"\\?\"的使用是安全的.我有更多15年的使用经验. (6认同)
  • 嗨,谢谢你的评论.是的,我意识到这些API存在(参见我的帖子).我不认为人们可以开始使用这个黑客并期望一切顺利.例如,\\?\ hack删除了一些解析.此外,我不清楚API的OUTPUT是如何受到影响的.我不清楚这个黑客的影响是什么.如果我沿着这条路走下去,我将不得不做很多测试.您是否有使用这些API的经验? (4认同)
  • 好的,"黑客"可能是错误的术语:)然而,我所说的是,它不仅仅是替代品.例如,如果使用".",相对路径将不起作用.或".."在路径中它将无法工作.某些API也会更改OUTPUT使用此"功能" - (例如,GetLongPathName()将返回包含"\\?\"的路径).另一方面,很高兴听到您有15年使用此API的经验 - 这让我的思绪更加轻松. (4认同)
  • 将 UNC 路径前缀为 \\?\host\share 不起作用。您必须使用 \\?\UNC\host\share。 (2认同)

Han*_*ant 10

这种限制融入了很多用C或C++编写的软件中.包括MSFT代码,虽然他们一直在削减它.它只是部分Win32限制,例如,它通过WIN32_FIND_DATA对文件名(而不是路径)的长度仍然有一个硬上限.甚至.NET有长度限制的一个原因.这不会很快消失,Win32仍然很强大,石器时代的C字符串不会消失.

毫无疑问,您的客户几乎不会对此表示同情,直到您可以向他们展示另一个失败的程序.但请确保您的代码可靠地检测到潜在的字符串缓冲区溢出,然后进行合理的诊断.没有同情轰炸堆腐败的程序.


Ste*_*utt 6

正如您所提到的,许多Windows Shell函数仅适用于MAX_PATH之前的路径.Windows XP和我认为Vista在使用长文件名嵌套目录时在Explorer中都有问题.我没有检查过Windows 7 - 也许他们已经解决了这个问题.遗憾的是,这意味着用户很难浏览这些文件.

如果你真的希望支持长路径,你需要检查你在Shell32.dll中使用的任何函数,这些函数采用路径来确保它们支持长路径.对于那些不需要的人,你必须使用Kernel32函数自己编写它们.

如果您决定使用Shell32并限制为MAX_PATH,则建议您编写代码以支持长文件路径.如果Microsoft稍后更改Shell32(或创建替代方案),您将能够更好地添加对它们的支持.

只是为问题添加另外两个维度,请记住文件名是UTF-16,您可能会遇到可能区分大小写的非NTFS或FAT文件系统!


Mic*_*yan 5

您自己的API不应硬编码路径长度(或任何其他硬限制)的固定限制; 但是,您不应该违反系统API的前提条件才能完成某项任务.恕我直言,Windows限制路径名称的长度是荒谬的,应该被视为一个错误.也就是说,我不会建议您不要尝试使用除记录之外的各种系统API,即使这会导致某些不期望的行为,例如限制最大路径长度.所以,简而言之,你的观点是完全公平的; 如果操作系统不支持它,那么操作系统不支持它.也就是说,您可能希望向用户明确说明这是Windows的限制,而不是您自己的代码.