如果我想分配一个char数组(在C中),保证它足够大以容纳任何有效的绝对路径+文件名,它需要多大。
在Win32上,有MAX_PATH定义。什么是Unix / linux的等价物?
答案 0 :(得分:53)
有PATH_MAX
,但有点问题。从realpath(3)手册页的错误部分:
此功能的POSIX.1-2001标准版本已被破坏 设计,因为不可能确定合适的尺寸 输出缓冲区, resolved_path 。根据POSIX.1-2001的缓冲区 尺寸 PATH_MAX 足够,但 PATH_MAX 无需定义 常数,可能必须使用pathconf(3)获得。和 因为一方面问pathconf(3)并没有真正帮助 POSIX警告pathconf(3)的结果可能很大 另一方面,不适合使用内存 pathconf(3)可能会返回-1表示 PATH_MAX 不是 界。
答案 1 :(得分:43)
到目前为止,关于* nix方面的其他答案似乎都是正确的,但我会在Windows上添加关于它的警告。
你被文件欺骗(遗漏)。
确实定义了 MAX_PATH
,甚至可能适用于存储在FAT或FAT32上的文件。但是,任何路径名都可以加\\?\
作为前缀,告诉Windows API忽略MAX_PATH
并让文件系统驱动程序自己决定。之后,定义变得模糊。
混合使用路径名实际上是Unicode(以及UTS-16)的事实,并且当使用“ANSI”API时,与内部Unicode名称之间的转换取决于一系列因素,包括当前的代码页,你有一个混乱的秘诀。
对Windows规则的详细说明是MSDN。这些规则比我在这里总结的要复杂得多。
修改:由于KitsuneYMG的评论,我在上面将\\.\
更改为\\?\
。
Windows路径和命名空间很复杂。有些人甚至认为他们太复杂了。复杂性的一个来源是Win32(现在是Win64)API是一个位于Windows NT本机系统之上的子系统。
没有任何前缀的路径在最广泛的Windows平台上兼容。如果它被限制为7位ASCII字符,那么它与版本2.0左右的16位DOS兼容(每当引入子目录时,实际上可能已经在DOS 3中;但是DOS 1.0只有根目录和{ {1}}字符没有特殊意义)。
\
前缀会导致路径名的余额逐字传递给相应的文件系统驱动程序,这会产生将限制放到\\?\
个字符的效果。如果长路径名也在网络共享上,则可以使用前缀为MAX_PATH
的扩展UNC名称,而不是正常的UNC名称\\?\UNC\server\share\
。使用此前缀限制了Win32和更高版本Windows平台的可移植性,但除非您需要在旧硬件上支持16位Windows,否则这不是一个大问题。
\\server\share\
前缀是另一种动物。它允许访问超出一组特殊命名设备的设备对象,这些设备由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 不是一个特殊的名称,如COM1。
我上面引用的MSDN页面有区别,我只是在原始答案中键入了错误的前缀。
答案 2 :(得分:18)
嗯,至少在Linux上,有:
PATH_MAX
(在limits.h
中定义)
FILENAME_MAX
(在stdio.h
中定义)
这两个都在我的系统(x86 Linux)上设置为4096
。
更新::Some info from the glibc manual on this
以下每个宏都在limits.h中定义,仅当系统对相关参数具有固定的统一限制时。如果系统允许不同的文件系统或文件具有不同的限制,则宏未定义;使用pathconf或fpathconf查找适用于特定文件的限制
答案 3 :(得分:6)
FILENAME_MAX是ISO C标准的一部分,适用于UNIX和Windows。但是,GNU C库文档包含以下警告:
“与PATH_MAX不同,即使没有实际限制,也会定义此宏。在这种情况下,它的值通常是一个非常大的数字。在GNU系统中总是如此。
使用备注:不要将FILENAME_MAX用作存储文件名的数组的大小!你不可能制造出那么大的阵列!使用动态分配。“
答案 4 :(得分:5)
您可以使用pathconf()
在运行时计算出来,但<limits.h>
中还有一个PATH_MAX预处理器定义。
答案 5 :(得分:2)
您可以使用realpath
函数为特定路径分配足够大的缓冲区。如果你传递一个空指针作为第二个参数,它将为路径分配一个足够大的缓冲区。手册页可能比我更好地解释了它:
realpath()展开所有符号链接,并解析对/./,/../和extra&#39; /&#39;的引用。由path命名的以null结尾的字符串中的字符,用于生成规范化的绝对路径名。生成的路径名将存储为空终止字符串,最多可达resolve_path所指向的缓冲区中的PATH_MAX字节数。生成的路径没有符号链接,/。/或/../ components。
如果resolve_path指定为NULL,则realpath()使用malloc(3)分配最多为PATH_MAX字节的缓冲区来保存已解析的路径名,并返回指向此缓冲区的指针。调用者应使用free(3)
解除分配此缓冲区
答案 6 :(得分:0)
limits.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
#define MAX_PATH 260