在 linux/unix 下是否有等效于 WinAPI 的 MAX_PATH?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/833291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there an equivalent to WinAPI's MAX_PATH under linux/unix?
提问by AndrewR
If I want to allocate a char array (in C) that is guaranteed to be large enough to hold any valid absolute path+filename, how big does it need to be.
如果我想分配一个保证足够大以容纳任何有效绝对路径+文件名的字符数组(在 C 中),它需要多大。
On Win32, there is the MAX_PATH define. What is the equivalent for Unix/linux?
在 Win32 上,有 MAX_PATH 定义。Unix/linux 的等价物是什么?
采纳答案by stefanB
There is a PATH_MAX
, but it is a bit problematic. From the bugs section of the realpath(3)man page:
有一个PATH_MAX
,但有点问题。从realpath(3)手册页的错误部分:
The POSIX.1-2001 standard version of this function is broken by design, since it is impossible to determine a suitable size for the output buffer, resolved_path. According to POSIX.1-2001 a buffer of size PATH_MAXsuffices, but PATH_MAXneed not be a defined constant, and may have to be obtained using pathconf(3). And asking pathconf(3)does not really help, since, on the one hand POSIX warns that the result of pathconf(3)may be huge and unsuitable for mallocing memory, and on the other hand pathconf(3)may return -1 to signify that PATH_MAXis not bounded.
此函数的 POSIX.1-2001 标准版本被设计破坏,因为无法确定输出缓冲区的合适大小,resolved_path。根据 POSIX.1-2001,大小为PATH_MAX的缓冲区就足够了,但PATH_MAX不需要是定义的常量,可能必须使用pathconf(3) 获得。并且询问pathconf(3)并没有真正的帮助,因为一方面 POSIX 警告pathconf(3)的结果可能很大并且不适合分配内存,另一方面 pathconf(3)可能返回 -1 到表示PATH_MAX 不受限制。
回答by AndrewR
Well, on Linux at least, there is:
好吧,至少在 Linux 上,有:
PATH_MAX
(defined inlimits.h
)FILENAME_MAX
(defined instdio.h
)
PATH_MAX
(定义于limits.h
)FILENAME_MAX
(定义于stdio.h
)
both of these are set to 4096
on my system (x86 Linux).
这两个都4096
在我的系统(x86 Linux)上设置为。
Update:: Some info from the glibc manual on this
更新::从这个glibc的手册一些信息
Each of the following macros is defined in limits.h only if the system has a fixed, uniform limit for the parameter in question. If the system allows different file systems or files to have different limits, then the macro is undefined; use pathconf or fpathconf to find out the limit that applies to a particular file
仅当系统对相关参数具有固定、统一的限制时,以下每个宏才在limits.h 中定义。如果系统允许不同的文件系统或文件有不同的限制,则宏是未定义的;使用 pathconf 或 fpathconf 找出适用于特定文件的限制
回答by unwind
You can use pathconf()
to figure out at run-time, but there's also a PATH_MAX preprocessor define in <limits.h>
.
您可以pathconf()
在运行时使用来计算,但在<limits.h>
.
回答by RBerteig
The other answers so far all seem right on point about the *nix side of things, but I'll add a warning about it on Windows.
到目前为止,其他答案似乎都与事情的 *nix 方面有关,但我会在 Windows 上添加有关它的警告。
You've been lied to (by omission) by the documentation.
你被文档骗了(被遗漏)。
MAX_PATH
is indeed defined, and probably even applies to files stored on FAT or FAT32. However, any path name can be prefixed by \\?\
to tell the Windows API to ignore MAX_PATH
and let the file system driver make up its own mind. After that, the definitions get fuzzy.
MAX_PATH
确实已定义,甚至可能适用于存储在 FAT 或 FAT32 上的文件。但是,任何路径名都可以以 为前缀\\?\
来告诉 Windows API 忽略MAX_PATH
并让文件系统驱动程序自己决定。在那之后,定义变得模糊。
Add to the mix the fact that path names are actually Unicode (well, UTS-16) and that when the "ANSI" API is used the conversion to and from the internal Unicode name is dependent on a bunch of factors including the current code page, and you have a recipe for confusion.
再加上路径名实际上是 Unicode(好吧,UTS-16),并且当使用“ANSI”API 时,内部 Unicode 名称之间的转换取决于一系列因素,包括当前的代码页,你有一个混乱的秘诀。
A good description of the rules for Windows is at MSDN. The rules are much more complicated than I've summarized here.
MSDN 上对 Windows 的规则进行了很好的描述。规则比我在这里总结的要复杂得多。
Edit:I changed \\.\
to \\?\
in the above thanks to the comment from KitsuneYMG.
编辑:由于 KitsuneYMG 的评论,我在上面更改\\.\
了\\?\
。
Windows paths and namespaces are complicated. Some might even argue they are too complicated. One source of complexity is that the Win32 (and now Win64) API is a subsystem that lays on top of the Windows NT native system.
Windows 路径和命名空间很复杂。有些人甚至可能会争辩说它们太复杂了。复杂性的一个来源是 Win32(现在是 Win64)API 是一个位于 Windows NT 本机系统之上的子系统。
A path without any prefix is compatible across the widest range of Windows platforms. If it is restricted to 7-bit ASCII characters, then it is compatible with 16-bit DOS since version 2.0 or so (whenever subdirectories were introduced, which might actually have been in DOS 3; but DOS 1.0 only had root directories and the \
character had no special meaning).
没有任何前缀的路径在最广泛的 Windows 平台上兼容。如果它被限制为 7 位 ASCII 字符,那么它从 2.0 版左右开始与 16 位 DOS 兼容(每当引入子目录时,它实际上可能已经在 DOS 3 中;但 DOS 1.0 只有根目录和\
字符没有特殊意义)。
The \\?\
prefix causes the balance of the path name to be passed on verbatim to the appropriate file system driver, which is what produces the effect of dropping the restriction to MAX_PATH
characters. If the long path name is also on a network share, then you can use an extended UNC name for it with the prefix \\?\UNC\server\share\
instead of the normal UNC name \\server\share\
. Using this prefix restricts portability to Win32 and later Windows platforms, but unless you require support for 16-bit Windows on legacy hardware, that isn't a big issue.
该\\?\
前缀使路径名的平衡上逐字传递到相应的文件系统驱动程序,这是产生下降的限制的影响MAX_PATH
人物。如果长路径名也在网络共享上,那么您可以为它使用带有前缀的扩展 UNC 名称,\\?\UNC\server\share\
而不是普通的 UNC 名称\\server\share\
。使用此前缀会限制对 Win32 和更高版本的 Windows 平台的可移植性,但除非您需要在旧硬件上支持 16 位 Windows,否则这不是大问题。
The \\.\
prefix is a different animal. It allows access to device objects beyond the set of specially named devices that are automatically mapped by Windows as special file names into every file folder. Those special names include CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. Note that all of those names are special whether or not an extension is used, or in any mix of upper or lower case. But it is possible that you have 10 or more COM ports installed. This happens quickly if you play with USB modems, or USB serial port adapters, since each unique USB-based serial port will be assigned a distinct COMn name. If you need to access the 50th serial port, then you can only do so with the name \\.\COM50
because COM50 is nota special name like COM1 is.
该\\.\
前缀是不同的动物。它允许访问一组特殊命名的设备之外的设备对象,这些设备对象由 Windows 作为特殊文件名自动映射到每个文件夹中。这些特殊名称包括 CON、PRN、AUX、NUL、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、LPT8 和 LPT9。请注意,无论是否使用扩展名,或大小写的任何混合,所有这些名称都是特殊的。但您可能安装了 10 个或更多 COM 端口。如果您使用 USB 调制解调器或 USB 串行端口适配器,这种情况会很快发生,因为每个唯一的基于 USB 的串行端口都将被分配一个不同的 COMn 名称。如果您需要访问第 50 个串口,那么您只能使用名称进行访问,\\.\COM50
因为 COM50不是像 COM1 这样的特殊名称。
The MSDN page I cited above had the distinction right, I simply typed the incorrect prefix in my original answer.
我上面引用的 MSDN 页面有区别,我只是在原始答案中输入了错误的前缀。
回答by cdarke
FILENAME_MAX is part of the ISO C standard, it works on UNIX and Windows. However, the GNU C library documentation contains the following warnings:
FILENAME_MAX 是 ISO C 标准的一部分,它适用于 UNIX 和 Windows。但是,GNU C 库文档包含以下警告:
"Unlike PATH_MAX, this macro is defined even if there is no actual limit imposed. In such a case, its value is typically a very large number. This is always the case on the GNU system.
“与 PATH_MAX 不同,即使没有施加实际限制,也会定义此宏。在这种情况下,它的值通常是一个非常大的数字。在 GNU 系统上总是如此。
Usage Note: Don't use FILENAME_MAX as the size of an array in which to store a file name! You can't possibly make an array that big! Use dynamic allocation."
使用说明:不要使用 FILENAME_MAX 作为存储文件名的数组大小!你不可能制作这么大的数组!使用动态分配。”
回答by Inactive - SO wronged Monica
You can use the realpath
function to allocate a buffer big enough for a specific path. If you pass it a null pointer as the 2nd argument it will allocate a buffer big enough for the path. The man page probably explains it better than I can:
您可以使用该realpath
函数为特定路径分配足够大的缓冲区。如果将空指针作为第二个参数传递给它,它将为路径分配一个足够大的缓冲区。手册页可能比我能更好地解释它:
realpath() expands all symbolic links and resolves references to /./, /../ and extra '/' characters in the null-terminated string named by path to produce a canonicalized absolute pathname. The resulting pathname is stored as a null-terminated string, up to a maximum of PATH_MAX bytes, in the buffer pointed to by resolved_path. The resulting path will have no symbolic link, /./ or /../ components.
If resolved_path is specified as NULL, then realpath() uses malloc(3) to allocate a buffer of up to PATH_MAX bytes to hold the resolved pathname, and returns a pointer to this buffer. The caller should deallocate this buffer using free(3).
realpath() 扩展所有符号链接并解析对 /./、/../ 和由 path 命名的以空字符结尾的字符串中的额外“/”字符的引用,以生成规范化的绝对路径名。生成的路径名存储为以空字符结尾的字符串,最多为 PATH_MAX 字节,存储在由 resolve_path 指向的缓冲区中。生成的路径将没有符号链接、/./ 或 /../ 组件。
如果将resolved_path 指定为NULL,则realpath() 使用malloc(3) 分配最多为PATH_MAX 字节的缓冲区来保存解析的路径名,并返回指向该缓冲区的指针。调用者应该使用 free(3) 解除分配这个缓冲区。
回答by Puddle
limits.h
限制.h
/*
* File system limits
*
* NOTE: Apparently the actual size of PATH_MAX is 260, but a space is
* required for the NUL. TODO: Test?
* NOTE: PATH_MAX is the POSIX equivalent for Microsoft's MAX_PATH; the two
* are semantically identical, with a limit of 259 characters for the
* path name, plus one for a terminating NUL, for a total of 260.
*/
#define PATH_MAX 260
minwindef.h
minwindef.h
#define MAX_PATH 260