在 linux/unix 下是否有与 WinAPI 的 MAX_PATH 等价的东西?

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

在 Win32上,有一个 MAX _ PATH 定义?

77597 次浏览

至少在 Linux 上是这样的:

  • PATH_MAX(在 limits.h中定义)

  • FILENAME_MAX(在 stdio.h中定义)

在我的系统(x86Linux)上,它们都被设置为 4096

更新: : 这是 glibc 手册上的一些信息

只有当系统对所讨论的参数有一个固定的、统一的限制时,以下每个宏才会在 limit s.h 中定义。如果系统允许不同的文件系统或文件有不同的限制,那么宏就是未定义的; 使用 pathconf 或 fpathconf 查找应用于特定文件的限制

您可以使用 pathconf()在运行时计算,但是在 <limits.h>中也有一个 PATH _ MAX 预处理器定义。

有一个 PATH_MAX,但它有点问题:

该函数的 POSIX.1-2001标准版中断为 设计,因为不可能确定一个合适的大小为 输出缓冲区,已解决的 _ 路径。根据 POSIX。1-2001的缓冲区 大小 最大路径足够,但 最大路径不需要被定义 常数,可能必须使用 Pathconf (3)来获得 问 Pathconf (3)并没有真正的帮助,因为,一方面 POSIX 警告说,Pathconf (3)的结果可能是巨大的 不适合错误的记忆,另一方面 Pathconf (3) 可能返回 -1以表示 最大路径不是 有界。

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

你被文件(忽略)欺骗了。

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

再加上路径名实际上是 Unicode (好吧,UTS-16) ,以及当使用“ ANSI”API 时,与内部 Unicode 名称的转换取决于一系列因素,包括当前代码页,你就有了混淆的处方。

关于 Windows 规则的一个很好的描述是 MSDN。规则比我在这里总结的要复杂得多。

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

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

没有任何前缀的路径可以在最广泛的 Windows 平台上兼容。如果它被限制为7位 ASCII 字符,那么它从2.0版本开始就与16位 DOS 兼容(无论何时引入子目录,实际上可能是在 DOS 3中; 但是 DOS 1.0只有根目录,而且 \字符没有特殊含义)。

\\?\前缀导致路径名的余额逐字传递给适当的文件系统驱动程序,这就产生了对 MAX_PATH字符放弃限制的效果。如果长路径名也在网络共享上,那么您可以使用前缀为 \\?\UNC\server\share\的扩展 UNC 名称来代替普通的 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 页面有区别,我只是在我的原始答案中输入了不正确的前缀。

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

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

使用说明: 不要使用 FILENAME _ MAX 作为存储文件名的数组的大小!你不可能做出这么大的阵列!使用动态分配。”

您可以使用 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.

如果已解析的 _ PATH 被指定为 NULL,那么 realpath ()使用 malloc (3)分配一个最大为 PATH _ MAX 字节的缓冲区来保存已解析的路径名,并返回一个指向这个缓冲区的指针。调用方应该使用 free (3)释放这个缓冲区。

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

极限

/*
* 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

#define MAX_PATH 260