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

时间:2010-05-13 09:50:17

标签: 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

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

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

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

我不是说可以我处理长路径,我问应该 I.是的我知道“\?\”unicode破解了一些Win32 API,但似乎这个hack并非没有风险(因为它改变了API解析路径的行为),并且所有API都不支持。

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

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

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

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

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

8 个答案:

答案 0 :(得分: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
  

等等

你会找到如下文字:

  

在此功能的ANSI版本中,   名称仅限于MAX_PATH   字符。将此限制扩展到   32,767宽字,打电话给   Unicode版本的功能和   将“\?\”添加到路径中。更多   信息,请参阅命名文件。

这个功能可以安全使用。如果您有CreateFile的文件句柄,则可以使用hFileReadFileWriteFile等所有其他功能而不受任何限制。

如果您编写的程序如病毒扫描程序或备份软件或服务器上运行的一些好软件,您应该编写程序,以便所有文件操作都支持最多 32K 字符的文件名,而不是{{ 1}}字符。

答案 1 :(得分:10)

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

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

答案 2 :(得分:6)

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

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

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

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

答案 3 :(得分:5)

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

答案 4 :(得分:2)

一种简单的方法,即使是不支持长度超过MAX_PATH的路径的软件,也可以创建具有长路径的文件:通过文件共享。

示例:

“C:\我的veeeeeeeeeeeeeeeeeeeeeeery looooooooooooooooooong文件夹”可以作为“数据”共享。然后,用户可以通过UNC路径\\ computer \ data或(甚至更短)通过驱动器号(M:\)访问该文件夹,假设M:映射到\\ computer \ data。

这通常发生在文件服务器上。

答案 5 :(得分:1)

路径通常可以大于260,一个例子是当符号链接嵌套时,有时甚至是故意重复。我认为程序员应该考虑他们是否希望他们的程序能够处理这些疯狂的大路径。 IMO,260太空了,但那只是我。我对此的回答是:

如果你必须如此深刻地问自己打破260 char限制,那么那可能是你应该做的。当我们即将做一些我们不确定的事情时,我们经常会寻求确认......

我认为API中任何地方的最大路径大约是32k长,但这取决于你。回到那个相当大的变化的一天(整个内存片段的一半!! sheesh!)但是现在,在我们居住的片段透明寻址环境中,所有内存都集中在平面上,32k是不是'AFAIK路径不需要那么长,除非你使用一些需要许多其他角色等的花哨的unicode语言。我们可以整天讨论这个问题,但你明白了。我希望这有助于.....或伤害?

答案 6 :(得分:1)

我正在进行一些C编程,我正在寻找一种方法来获取给定文件名的最大长度,在搜索MAX_PATH之后我偶然发现了这个问题,并在som对这个问题的想法之后以及在阅读了这个问题之后线程我得出以下结论。

所以我理解NTFS支持的文件名长度最多为32.767个字符,但是,根据知识,FAT16只支持11个字符的文件名,8 + 3,所以在reallity操作系统中应该有一个我们的程序可以调用dertemine的函数最大文件名大小,因为所有文件系统都有不同的限制,包括文件名的长度。

因此,最终的结论必须是,由于我们开发人员不知道数据将存储在哪个文件系统中,因此唯一的解决方案必须是尝试和错误方法。

答案 7 :(得分:0)

不是严格地回答您的具体问题,但它可能会帮助那些需要处理长文件名的人。

Delimon库是Microsoft TechNet上基于.NET Framework 4的库,用于克服长文件名问题:

<强> Delimon.Win32.I​O Library (V4.0)

它有自己的System.IO关键方法版本。例如,您将替换:

  

System.IO.Directory.GetFiles

  

Delimon.Win32.IO.Directory.GetFiles

可让您处理长文件和文件夹。

来自网站:

  

Delimon.Win32.IO取代了System.IO和。的基本文件功能   支持File&amp;文件夹名称最多为32,767个字符。

     

此库是在.NET Framework 4.0上编写的,也可以使用   在x86&amp; x64系统。文件&amp;文件夹限制标准   System.IO命名空间可以处理a中包含260个字符的文件   文件名和文件夹名中的240个字符(通常是MAX_PATH   配置为260个字符)。通常你会碰到   System.IO.PathTooLongException标准.NET库出错。