在linux / unix下是否有相当于WinAPI的MAX_PATH?

时间:2009-05-07 07:16:36

标签: c++ c linux unix posix

如果我想分配一个char数组(在C中),保证它足够大以容纳任何有效的绝对路径+文件名,它需要多大。

在Win32上,有MAX_PATH定义。什么是Unix / linux的等价物?

7 个答案:

答案 0 :(得分:53)

PATH_MAX,但有点问题。从realpath(3)手册页的错误部分:

  

此功能的POSIX.1-2001标准版本已被破坏   设计,因为不可能确定合适的尺寸   输出缓冲区, resolved_pa​​th 。根据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)

解除分配此缓冲区

http://linux.die.net/man/3/realpath

答案 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