我应该处理长于 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 托管驱动器上的文件。
所以我的问题是这样的。我应该关心吗?
我并不是说我可以处理长路径,而是我应该处理长路径。是的,我知道某些代码上的“\?\”unicode hack Win32 API,但这种黑客攻击似乎并非没有风险(因为它改变了 API 解析路径的行为),而且并非所有 API 都支持。
所以无论如何,让我声明我的立场/断言:
- 首先,用户能够打破此限制的唯一方法是她使用的应用程序使用特殊的 Unicode hack。这是一个 PDF 文件,所以她使用的 PDF 工具可能使用了这个 hack。
- 我尝试重现这个(通过使用 unicode hack)并进行实验。我发现虽然该文件出现在资源管理器中,但我无法对其执行任何操作。我无法打开它,无法选择“属性”(Windows 7)。其他常见应用程序无法打开该文件(例如IE、Firefox、记事本)。资源管理器也不会让我创建太长的文件/目录 - 它只是拒绝。命令行工具 cmd.exe 也是如此。
基本上,人们可以这样看待它:rouge 工具允许用户创建一个许多 Windows(例如资源管理器)无法访问的文件。我可以认为我不应该处理这个问题。
(顺便说一句,这并不是对较短的最大路径长度的投票:我认为 260 个字符是一个笑话,我只是说如果 Windows shell 和某些 API 无法处理 > 260 那么为什么应该我?)。
那么,这是一个公平的观点吗?我应该说“不是我的问题”吗?
更新:刚刚有另一个用户遇到了同样的问题。这次是 mp3 文件。我错过了什么吗?这些用户如何创建违反 MAX_PATH 规则的文件?
Just had an interesting case.
My software reported back a failure caused by a path being longer than MAX_PATH.
The path was just a plain old document in My Documents, e.g.:
C:\Documents and Settings\Bill\Some Stupid FOlder Name\A really ridiculously long file thats really very very very..........very long.pdf
Total length 269 characters (MAX_PATH==260).
The user wasn't using a external hard drive or anything like that. This was a file on an Windows managed drive.
So my question is this. Should I care?
I'm not saying can I deal with the long paths, I'm asking should I. Yes I'm aware of the "\?\" unicode hack on some Win32 APIs, but it seems this hack is not without risk (as it's changing the behaviour of the way the APIs parse paths) and also isn't supported by all APIs .
So anyway, let me just state my position/assertions:
- First presumably the only way the user was able to break this limit is if the app she used uses the special Unicode hack. It's a PDF file, so maybe the PDF tool she used uses this hack.
- I tried to reproduce this (by using the unicode hack) and experimented. What I found was that although the file appears in Explorer, I can do nothing with it. I can't open it, I can't choose "Properties" (Windows 7). Other common apps can't open the file (e.g. IE, Firefox, Notepad). Explorer will also not let me create files/dirs which are too long - it just refuses. Ditto for command line tool cmd.exe.
So basically, one could look at it this way: a rouge tool has allowed the user to create a file which is not accessible by a lot of Windows (e.g. Explorer). I could take the view that I shouldn't have to deal with this.
(As an aside, this isn't an vote of approval for a short max path length: I think 260 chars is a joke, I'm just saying that if Windows shell and some APIs can't handle > 260 then why should I?).
So, is this a fair view? Should I say "Not my problem"?
UPDATE: Just had another user with the same problem. This time an mp3 file. Am I missing something? How can these users be creating files that violate the MAX_PATH rule?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
严格来说,这并不是对您的具体问题的答案,但它可能会帮助那些确实需要处理长文件名的人。
Delimon 库是 Microsoft TechNet 上基于 .NET Framework 4 的库,用于克服长文件名问题:
Delimon.Win32.IO 库(V4.0)。
它有自己版本的 System.IO 关键方法。例如,您可以替换:
与
可以让您处理长文件和文件夹。
来自网站:
Not strictly an answer to your specific question, but it might help those who do need to handle long file names.
The Delimon library is a .NET Framework 4 based library on Microsoft TechNet for overcoming the long filenames problem:
Delimon.Win32.IO Library (V4.0).
It has its own versions of key methods from System.IO. For example, you would replace:
with
which will let you handle long files and folders.
From the website:
这不是一个真正的问题。 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
的文件句柄,您可以使用hFile
使用的所有其他函数(ReadFile
、WriteFile
等)。 ) 没有任何限制。如果您编写诸如病毒扫描程序或备份软件之类的程序或在服务器上运行的某些优秀软件,您应该编写程序,以便所有文件操作都支持最多 32K 个字符的文件名,而不是
MAX_PATH< /code> 字符。
It's not a real problem. NTFS support filenames up to 32K (32,767 wide characters). You need only use correct API and correct syntax of filenames. The base rule is: the filename should start with
'\\?\'
(see http://msdn.microsoft.com/en-us/library/aa365247(v=VS.85).aspx) like\\?\C:\Temp
. The same syntax you can use with UNC:\\?\UNC\Server\share\Path
. Important to understand that you can use only a small subset of API function. For example look at MSDN description of functionsyou will find text like :
This functions you can safe use. If you have a file handle from
CreateFile
you can use all other functions usedhFile
(ReadFile
,WriteFile
etc.) without any restriction.If you write a program like virus scanner or backup software or some good software running on a server you should write your program so, that all file operations support filenames up to 32K characters and not
MAX_PATH
characters.许多用 C 或 C++ 编写的软件都存在这种限制。包括 MSFT 代码,尽管他们一直在努力改进。这只是 Win32 的部分限制,例如通过 WIN32_FIND_DATA,它仍然对文件名(不是路径)的长度有硬性上限。甚至 .NET 也有 长度限制。这种情况不会很快消失,Win32 仍然很强大,石器时代的 C 字符串也不会消失。
毫无疑问,你的客户不会对此表示同情,可能直到你向他们展示另一个以同样方式失败的程序为止。但是,请确保您的代码能够可靠地检测到潜在的字符串缓冲区溢出,然后进行合理的诊断。不同情对堆损坏进行轰炸的程序。
This limitation is baked into a lot of software written in C or C++. Including MSFT code, although they've been chipping away at it. It is only partly a Win32 limitation, it still has a hard upper limit on the length of a file name (not path) through WIN32_FIND_DATA for example. One reason that even .NET has length restrictions. This is not going away any time soon, Win32 is still going strong and the stone-age C string won't disappear.
Your customer will have little sympathy with it, no doubt, probably until you can show them another program that fails the same way. Do however make sure that your code reliably can detect the potential string buffer overflow, followed by a reasonable diagnostic. No sympathy for programs bombing on heap corruption.
正如您提到的,许多 Windows Shell 函数仅适用于 MAX_PATH 之前的路径。我相信 Windows XP 和 Vista 在资源管理器中嵌套具有长文件名的目录时都会出现问题。我没有检查过 Windows 7 - 也许他们已经解决了这个问题。不幸的是,这意味着用户很难浏览这些文件。
如果您确实希望支持长路径,则需要检查 Shell32.dll 中使用的任何采用路径的函数,以确保它们支持长路径。对于那些不需要的,您必须使用 Kernel32 函数自己编写它们。
如果您决定使用 Shell32 并限制为 MAX_PATH,那么建议您编写代码来支持长文件路径。如果 Microsoft 稍后更改 Shell32(或创建替代方案),您将能够更好地添加对它们的支持。
只是为了给问题添加另外几个维度,请记住文件名是 UTF-16,并且您可能会遇到区分大小写的非 NTFS 或 FAT 文件系统!
As you mentioned many of the Windows Shell functions only work on paths up to MAX_PATH. Windows XP and I believe Vista both have problems in Explorer when nesting directories with long file names. I've not checked Windows 7 - perhaps they have fixed that. This unfortunately means that users have a hard time browsing these file.
If you really wish to support long paths you'll need to check any functions you are using in Shell32.dll that take paths to ensure they support long paths. For those that don't you'll have to use write them yourself using Kernel32 functions.
If you decide to use Shell32 and be limited to MAX_PATH, writing your code to support long file paths would be advisable. If Microsoft later change Shell32 (or create an alternative), you will be better positioned to add support for them.
Just to add another couple of dimensions to the problem, remember that filenames are UTF-16, and you may encounter non NTFS or FAT filesystems that may be case sensitive!
您自己的 API 不应硬编码路径长度的固定限制(或任何其他硬限制);但是,您不应为了完成某些任务而违反系统 API 的先决条件。恕我直言,Windows 限制路径名长度的事实是荒谬的,应该被视为一个错误。也就是说,不,我建议您不要尝试使用记录之外的各种系统 API,即使这会导致某些不良行为,例如最大路径长度的限制。所以,简而言之,你的观点是完全公平的;如果操作系统不支持它,那么操作系统不支持它。也就是说,您可能希望向用户明确这是 Windows 的限制,而不是您自己的代码的限制。
Your own APIs should not hard-code a fixed limit on the path length (or any other hard limits); however, you shouldn't violate the preconditions of the system APIs in order to accomplish some task. IMHO, the fact that Windows limits the length of path names is absurd and should be considered a bug. That said, no I would suggest you not attempt to use the various system APIs other than as documented, even if that results in certain undesireable behavior such as limits to the maximum path length. So, in short, your view is completely fair; if the OS doesn't support it, then the OS doesn't support it. That said, you may want to make it clear to users that this is a limitation of Windows and not of your own code.
即使软件不支持长于 MAX_PATH 的路径,也可以创建这些具有长路径的文件,这是一种简单的方法:通过文件共享。
示例:
“C:\My veeeeeeeeeeeeeeeeeeeery looooooooooooooooooong 文件夹”可以作为“数据”共享。然后,用户可以通过 UNC 路径 \\computer\data 或(甚至更短)通过驱动器号 (M:\) 访问该文件夹,假设 M: 映射到 \\computer\data。
这种情况经常发生在文件服务器上。
One easy way how these files with long paths could be created even by software that does not support paths longer than MAX_PATH: through a file share.
Example:
"C:\My veeeeeeeeeeeeeeeeeeeeery looooooooooooooooooong folder" could be shared as "data". Users could then access that folder through the UNC path \\computer\data or (even shorter) through a drive letter (M:\) assuming that M: is mapped to \\computer\data.
This often happens on file servers.
路径通常可以大于 260,一个例子是符号链接嵌套并且有时甚至是故意重复的。我认为程序员应该考虑他们是否希望他们的程序处理这些非常大的路径。 IMO,260 空间足够了,但那只是我。我对此的回答是:
如果您必须深入地问自己是否要打破 260 个字符的限制,那么这可能就是您应该做的。当我们要做一些我们不确定的事情时,我们经常会寻求确认...
我认为 API 中任何地方的最大路径大约是 32k 长,但这取决于你。在当时,这是一个相当大的变化(整个内存段的一半!!天啊!),但现在,在我们生活的段透明寻址环境中,所有内存都堆在一起,32k没什么……据我所知,路径不需要那么长,除非您使用某种奇特的 unicode 语言,需要大量其他字符等等。我们可以整天谈论这个,但您明白了。我希望这有帮助……还是有伤害?
Paths often can be bigger than 260, one example would be when symlinks get nested and repeat over and over sometimes even on purpose. I think programmers should think about whether they want their program to handle these insanely large paths or not. IMO, 260 is PLENTY of space but thats just me. My answer to this is:
if you have to ask yourself so deeply about breaking the 260 char limit, then thats probably what you should do. We often look for confirmation when we are about to do something that we are unsure about...
I think the maximum path anywhere in the API is about 32k long but thats up to you. Back in the day that was a pretty big chunk of change (half of an entire memory segment!! sheesh!) but nowdays, in the segment-transparent addressing environment in which we live, where all memory is heaped together on the flat, 32k is nothin'... AFAIK paths wouldn't need to be that long unless you are using some fancy unicode language that requires lots of other characters, etc, etc.. we could blab about this all day but you get the idea. I hope this helps..... or hurts?
我正在做一些 C 编程,我正在寻找一种方法来获取给定文件名的最大长度,在搜索 MAX_PATH 之后,我偶然发现了这个线程,在对这个问题进行了一些思考之后,在阅读了这个线程上的评论后,我有得出以下结论。
所以我知道NTFS支持最大长度为32.767个字符的文件名,但是,根据知识FAT16只支持11个字符的文件名,8 + 3,所以实际上操作系统应该有一个我们的程序可以调用的函数来确定最大文件名大小,只是因为所有文件系统都有不同的限制,包括文件名的长度。
所以最终的结论一定是,由于我们开发人员不知道数据将存储在哪个文件系统中,因此唯一的解决方案必须是尝试和错误方法。
I am doung some C programming and I was searching for a way to get the maximum length of a given filename, after a search for MAX_PATH I stumbled to this thread and after som thoughts on this matter and after reading the comments on this thread I have come to the following conclusion.
So I understand that NTFS support filenames up to 32.767 characters in length, however, according to knowledge FAT16 only support 11 character filenames, 8 + 3, so in reallity operating systems should have a function which our program can call to dertemine the maximum filename size, simply because all filesystems have different limitations including the length of the filename.
So the end conclusion must be that since us, the developers, don't know anything about which filesystem the data is going to be stored in, so therefore the only solution must be an try and error method.