Why does the 260 character path length limit exist

2018-12-31 07:20发布

I have come up against this problem a few times at inopportune moments:

  • trying to work on open source Java projects with deep paths
  • Storing deep Fitnesse wiki trees in source control
  • An error trying to use Bazaar to import my source control tree

Why does this limit exist?

Why hasn't it been removed yet?

How do you cope with the path limit? ... and no, switching to linux or Mac OS X is not a valid answer to this question ;)

12条回答
十年一品温如言
2楼-- · 2018-12-31 07:59

This is not strictly true as the NTFS filesystem supports paths up to 32k characters. You can use the win32 api and "\\?\" prefix the path to use greater than 260 characters.

A detailed explanation of long path from the .Net BCL team blog.
A small excerpt highlights the issue with long paths

Another concern is inconsistent behavior that would result by exposing long path support. Long paths with the \\?\ prefix can be used in most of the file-related Windows APIs, but not all Windows APIs. For example, LoadLibrary, which maps a module into the address of the calling process, fails if the file name is longer than MAX_PATH. So this means MoveFile will let you move a DLL to a location such that its path is longer than 260 characters, but when you try to load the DLL, it would fail. There are similar examples throughout the Windows APIs; some workarounds exist, but they are on a case-by-case basis.

查看更多
孤独总比滥情好
3楼-- · 2018-12-31 08:03

While everybody cries that 260 chars are awful in 2017, somehow nobody cries that most gnu shitware breaks if it encounters spaces in paths. Not even unicode. And speaking of inherently broken functions - think of your favourite strcpy without the n. Even malloc is broken on linux because it relies on page faults to actually commit the reserved address space (which is slow and bug prone). Nobody is perfect, and ignorance is not a valid reason to whine.

Also, the commenters somehow don't say what exactly is broken.

There are 3 things which are broken:

  • certain calls (I'm only aware of Get/SetCurrentDirectoryW) are limited to a single thread and 260 chars no matter what. So essentially relative paths are broken on Windows, emulate them just like you emulate fork if you are forced to.

  • the software ported from non-windows which inherently relies on non-windows concepts (including the concept of current dir/relative paths, see above)

  • the software which is written from scratch for Windows, but still uses an ancient API (but see above - while there are APIs for general filesystem access, there's no API for current directory on Windows which works past MAX_PATH)

As for why it's still broken - in my opinion MS fixed everything which is fixable. I think it's inheritance of current directory by child processes that doesn't allow GetCurrentDirectoryW to be fixed.

查看更多
几人难应
4楼-- · 2018-12-31 08:05

Quoting this article http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath

Maximum Path Length Limitation

In the Windows API (with some exceptions discussed in the following paragraphs), the maximum length for a path is MAX_PATH, which is defined as 260 characters. A local path is structured in the following order: drive letter, colon, backslash, name components separated by backslashes, and a terminating null character. For example, the maximum path on drive D is "D:\some 256-character path string<NUL>" where "<NUL>" represents the invisible terminating null character for the current system codepage. (The characters < > are used here for visual clarity and cannot be part of a valid path string.)

Now we see that it is 1+2+256+1 or [drive][:\][path][null] = 260. One could assume that 256 is a reasonable fixed string length from the DOS days. And going back to the DOS APIs we realize that the system tracked the current path per drive, and we have 26 (32 with symbols) maximum drives (and current directories).

The INT 0x21 AH=0x47 says “This function returns the path description without the drive letter and the initial backslash.” So we see that the system stores the CWD as a pair (drive, path) and you ask for the path by specifying the drive (1=A, 2=B, …), if you specify a 0 then it assumes the path for the drive returned by INT 0x21 AH=0x15 AL=0x19. So now we know why it is 260 and not 256, because those 4 bytes are not stored in the path string.

Why a 256 byte path string, because 640K is enough RAM.

查看更多
萌妹纸的霸气范
5楼-- · 2018-12-31 08:07

One way to cope with the path limit is to shorten path entries with symbolic links.

For example:

  1. create a C:\p directory to keep short links to long paths
  2. mklink /J C:\p\foo C:\Some\Crazy\Long\Path\foo
  3. add C:\p\foo to your path instead of the long path
查看更多
只靠听说
6楼-- · 2018-12-31 08:08

As to why this still exists - MS doesn't consider it a priority, and values backwards compatibility over advancing their OS (at least in this instance).

A workaround I use is to use the "short names" for the directories in the path, instead of their standard, human-readable versions. So e.g. for C:\Program Files\ I would use C:\PROGRA~1\ You can find the short name equivalents using dir /x.

查看更多
孤独寂梦人
7楼-- · 2018-12-31 08:11

Another way to cope with it is to use Cygwin, depending on what do you want to do with the files (i.e. if Cygwin commands suit your needs)

For example it allows to copy, move or rename files that even Windows Explorer can't. Or of course deal with the contents of them like md5sum, grep, gzip, etc.

Also for programs that you are coding, you could link them to the Cygwin DLL and it would enable them to use long paths (I haven't tested this though)

查看更多
登录 后发表回答