I just got burned by the 260 character path limitation in Windows. Why did Microsoft decided to limit paths to 3 characters for drive + 256 characters + 1 character for the terminator? Mac OS of the same vintage has a 31 character filename limit but no path limit since the FSSpec stored volume number, refnum, and 31 character filename (Pascal string as length byte + 31 characters). HFS running on 512k of RAM could support long paths, but Windows 3.1 and 95 cannot. Newer versions of Windows can under some limited circumstances break the 260 character path limit, but they are limited by compatibility to Win32 headers.
In the Windows world, the
MAX_PATH 260-character limit dates back to the introduction of the Win32 APIs; it is for example documented in
GetWindowsDirectory. Before that, Windows (at least in version 3) documented a 144-character limit; see for example
As far as why the path limit is 260 characters, the general answer you’ll find on the Internet is backwards compatibility. OK, that’s often the case in computing in general, and on Windows in particular (which is why many 30-year-old Windows programs can still be made to run on modern Windows, at least on 32-bit systems). The question then becomes, backwards compatibility with what?
The obvious answer would be DOS, and perhaps Win16. But DOS has a maximal path limit of 66 characters, constrained by its CDS (current directory structure) which has room for a 67-byte nul-terminated string to store each drive’s path (including drive letter, if appropriate). DOS-based versions of Windows couldn’t change this, since they had to maintain compatibility with DOS programs — imagine being able to store a file in a deeply-nested directory, only to have it be inaccessible from DOS! So the DOS limit doesn’t explain the 256-character limit in Win32. (I’m ignoring network drives here.)
(Incidentally, you can achieve the latter effect by mounting a FAT drive under Linux: Linux allows much longer paths on FAT than DOS or Windows can handle, so you can create directories which are so deeply nested that DOS can’t handle them properly.)
Digging further reveals something interesting; old Windows headers define, in
#if defined(__OS2__) || defined(__WIN32__) #define _MAX_PATH 260 #define _MAX_DRIVE 3 #define _MAX_DIR 256 #define _MAX_FNAME 256 #define _MAX_EXT 256 #else #define _MAX_PATH 80 #define _MAX_DRIVE 3 #define _MAX_DIR 66 #define _MAX_FNAME 9 #define _MAX_EXT 5 #endif
MAX_PATH makes sense for DOS and Win16, based on the CDS above: that’s just enough room for a 66-byte path,
\, 12-byte filename (11 bytes stored on disk and
. separator), and a nul terminator.
The interesting part is the other definition: the famous 260-byte limit... defined for Win32, and for OS/2! Reading through the OS/2 APIs doesn’t help much, because they’re all designed to not have documented limits (programs are supposed to call
QSV_MAX_PATH_LENGTH to find the maximum path length), as are in fact most of the Windows APIs (e.g.
GetCurrentDirectory which takes a buffer and allocated length, and indicates the required length if the buffer isn’t big enough). But Inside OS/2, in its description of the file system name space, says
All OS/2 filename and pathname interfaces, such as DosOpen, DosFindNext, and so on, are designed to take name strings of arbitrary length. Applications should use name buffers of at least 256 characters to ensure that a long name is not truncated.
So I get the impression that the 256-character limit is part of OS/2’s legacy, and that when it was chosen, 256 characters was considered sufficient for “name strings of arbitrary length”.