70

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

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

4

7 回答 7

63

有一个PATH_MAX,但它有点问题。从realpath(3)手册页的 bugs 部分:

此函数的 POSIX.1-2001 标准版本被设计破坏,因为无法确定输出缓冲区的合适大小resolve_path。根据 POSIX.1-2001,大小为PATH_MAX的缓冲区就足够了,但PATH_MAX不必是定义的常量,可能必须使用pathconf(3)获得。并且询问pathconf(3)并没有真正的帮助,因为一方面 POSIX 警告pathconf(3)的结果可能很大并且不适合分配内存,另一方面 pathconf(3)可能会返回 -1 到表示PATH_MAX 不受限制

于 2009-05-07T07:24:15.143 回答
49

到目前为止,关于 *nix 方面的其他答案似乎都是正确的,但我会在 Windows 上添加一个关于它的警告。

您被文档欺骗(通过遗漏)。

MAX_PATH确实已定义,甚至可能适用于存储在 FAT 或 FAT32 上的文件。但是,任何路径名都可以加上前缀\\?\来告诉 Windows API 忽略MAX_PATH并让文件系统驱动程序自己决定。在那之后,定义变得模糊。

再加上路径名称实际上是 Unicode(嗯,UTS-16)的事实,并且当使用“ANSI”API 时,与内部 Unicode 名称之间的转换取决于一系列因素,包括当前代码页,你有一个混乱的秘诀。

MSDN上对 Windows 的规则进行了很好的描述。规则比我在这里总结的要复杂得多。

编辑:感谢 KitsuneYMG 的评论,我改成\\.\了上面的。\\?\

Windows 路径和命名空间很复杂。有些人甚至可能认为它们太复杂了。复杂性的一个来源是 Win32(现在是 Win64)API 是一个位于 Windows NT 本地系统之上的子系统。

没有任何前缀的路径在最广泛的 Windows 平台上兼容。如果它仅限于 7 位 ASCII 字符,那么它与 2.0 版左右的 16 位 DOS 兼容(无论何时引入子目录,实际上可能已经在 DOS 3 中;但 DOS 1.0 只有根目录和\字符没有特殊意义)。

前缀导致路径名的\\?\平衡被逐字传递给适当的文件系统驱动程序,这产生了删除对MAX_PATH字符的限制的效果。如果长路径名也在网络共享上,那么您可以使用带有前缀的扩展 UNC 名称,\\?\UNC\server\share\而不是普通的 UNC 名称\\server\share\。使用此前缀会限制对 Win32 和更高版本的 Windows 平台的可移植性,但除非您需要在旧硬件上支持 16 位 Windows,否则这不是一个大问题。

\\.\前缀是另一种动物。它允许访问一组特殊命名的设备之外的设备对象,这些设备由 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 这样的特殊名称。

我上面引用的 MSDN 页面有区别,我只是在原始答案中输入了不正确的前缀。

于 2009-05-08T01:30:34.190 回答
20

好吧,至少在 Linux 上,有:

  • PATH_MAX(定义在limits.h

  • FILENAME_MAX(定义在stdio.h

这两个都设置4096在我的系统(x86 Linux)上。

更新::来自glibc 手册的一些信息

仅当系统对相关参数具有固定、统一的限制时,才会在 limits.h 中定义以下每个宏。如果系统允许不同的文件系统或文件有不同的限制,那么宏是未定义的;使用 pathconf 或 fpathconf 找出适用于特定文件的限制

于 2009-05-07T07:19:09.320 回答
6

FILENAME_MAX 是 ISO C 标准的一部分,它适用于 UNIX 和 Windows。但是,GNU C 库文档包含以下警告:

“与 PATH_MAX 不同,即使没有施加实际限制,也会定义此宏。在这种情况下,它的值通常是一个非常大的数字。在 GNU 系统上总是如此。

使用说明:不要使用 FILENAME_MAX 作为存储文件名的数组的大小!你不可能做一个那么大的数组!使用动态分配。”

于 2011-06-28T17:20:42.253 回答
5

您可以pathconf()在运行时使用它来计算,但在<limits.h>.

于 2009-05-07T07:20:20.503 回答
3

您可以使用该realpath函数为特定路径分配足够大的缓冲区。如果您将空指针作为第二个参数传递给它,它将为路径分配一个足够大的缓冲区。手册页可能比我能更好地解释它:

realpath() 扩展所有符号链接并解析对 /./、/../ 和由 path 命名的以 null 结尾的字符串中的额外“/”字符的引用,以生成规范化的绝对​​路径名。生成的路径名存储为以 null 结尾的字符串,最多 PATH_MAX 个字节,存储在 resolved_pa​​th 指向的缓冲区中。生成的路径将没有符号链接、/./ 或 /../ 组件。

如果将 resolved_pa​​th 指定为 NULL,则 realpath() 使用 malloc(3) 分配一个最多 PATH_MAX 字节的缓冲区来保存已解析的路径名,并返回指向此缓冲区的指针。调用者应该使用 free(3) 释放这个缓冲区。

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

于 2014-05-13T19:12:12.893 回答
1

限制.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
于 2018-12-20T16:07:53.260 回答