Linux 在多大程度上支持超过 255 字节的文件名?

Linux 在多大程度上支持超过 255 字节的文件名?

问一下Linux的255字节文件名限制昨天,答案是这是一个不能/不会轻易改变的限制。但我记得大多数Linux都支持NTFS,其最大文件名长度是255个UTF-16字符。

因此,我创建了一个 NTFS 分区,并尝试将一个文件命名为 160 个字符的日语字符串,其 UTF-8 中的字节为 480。我预计它不会起作用,但它起作用了,如下所示。当文件名是 480 字节时,它如何工作? 255 字节的限制是否仅针对某些文件系统,Linux 本身可以处理超过 255 字节的文件名?

在此输入图像描述

----附言-----

字符串的开头部分是日本著名的古文《方丈记》。这是字符串。

ゆく河の流れは绝えずして、しかももとの水にあらず。よどみに浮かぶうたかたは、かつ消えかつ结びて、久しくとどまりたるためしなし。世の中にある人とすみかと、またかくのごとしたましきの都のうちに、栋を并べ、甍を争へる、高き、卑しき、人の住まひは、世々を経て尽きせぬものなれど、これをまことかと寻ぬれば、昔ありし家はまれなり。

我曾经用过这个网络应用程序计算 UTF-8 字节数。

在此输入图像描述

答案1

答案通常是“视情况而定”。

尤其是 NTFS 实现,它报告最大文件名长度为 255statvfs调用者,因此将其解释为 255 字节限制的调用者可能会预先避免在 NTFS 上有效的文件名。然而,大多数程序不会提前检查这一点(甚至不会检查NAME_MAX),而是依靠ENAMETOOLONG错误来捕获错误。在大多数情况下,重要的限制是PATH_MAX,而不是NAME_MAX;这就是在操作文件名时通常用于分配缓冲区的内容(对于不动态分配路径缓冲区的程序,如操作系统所期望的那样赫德没有任意限制)。

NTFS 实现本身并不检查文件名长度(以字节为单位),而是始终检查 2 字节字符;无法用 255 个 2 字节元素的数组表示的文件名将导致错误ENAMETOOLONG

请注意,NTFS 通常由 Linux 上的 FUSE 驱动程序处理。内核驱动程序目前仅支持 UCS-2 字符,但是保险丝驱动器支持 UTF-16 代理项对(字符长度相应减少)。

答案2

文件名长度的限制确实是在文件系统内部编码的,例如ext4,来自https://en.wikipedia.org/wiki/Ext4:

最大限度。文件名长度 255 字节

https://en.wikipedia.org/wiki/XFS:

最大限度。文件名长度 255 字节

https://en.wikipedia.org/wiki/Btrfs:

最大限度。文件名长度 255 个 ASCII 字符(对于多字节字符编码,例如 Unicode,长度较短)

https://en.wikipedia.org/wiki/NTFS:

最大限度。文件名长度 255 个 UTF-16 代码单元

有关许多文件系统的这些限制的概述可以在以下位置找到:https://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits。在那里您还可以看到 ReiserFS 有更高的限制(几乎 4K),但内核本身(VFS 内部,内核虚拟文件系统)有 255 字节的限制。

您的文本使用 NTFS 中使用的 160 个 UTF-16 字符:

echo ゆく河の流れは絶えずして、しかももとの水にあらず。よどみに浮かぶうたかたは、かつ消えかつ結びて、久しくとどまりたるためしなし。世の中にある人とすみかと、またかくのごとし。たましきの都のうちに、棟を並べ、甍を争へる、高き、卑しき、人の住まひは、世々を経て尽きせぬものなれど、これをまことかと尋ぬれば、昔ありし家はまれなり。 > jp.txt
iconv -f utf-8 -t utf-16 jp.txt > jp16.txt
ls -ld jp*.txt
cat jp16.txt | hexdump -C

这显示 0x140 = 320 字节(加上 2 字节前置字节顺序标记 (BOM)(如果使用))。换句话说,160 个 UTF-16 字符,因此低于 NTFS 中 255 个 UTF-16 字符的限制,但超过 255 个字节。

(这里忽略换行符)

答案3

所以,这就是我发现的。

核心工具不特别关心文件名长度,只需处理用户输入而不管其长度如何,即零检查。

即这有效(文件名长度以字节为单位 462!):

name="和総坂裁精座回資国定裁出観産大掲記労。基利婚岡第員連聞余枚転屋内分。妹販得野取戦名力共重懲好海。要中心和権瓦教雪外間代円題気変知。貴金長情質思毎標豊装欺期権自馬。訓発宮汚祈子報議広組歴職囲世階沙飲。賞携映麻署来掲給見囲優治落取池塚賀残除捜。三売師定短部北自景訴層海全子相表。著漫寺対表前始稿殺法際込五新店広。"
cd /mnt/ntfs
touch "$name"

即使这样也有效

echo 123 > "$name"
cat "$name"
123

然而,一旦您尝试将上述文件复制到任何经典 Linux 文件系统,操作就会失败:

cp "$name" /tmp
cp: cannot stat '/tmp/和総坂裁精座回資国定裁出観産大掲記労。基利婚岡第員連聞余枚転屋内分。妹販得野取戦名力共重懲好海。要中心和権瓦教雪外間代円題気変知。貴金長情質思毎標豊装欺期権自馬。訓発宮汚祈子報議広組歴職囲世階沙飲。賞携映麻署来掲給見囲優治落取池塚賀残除捜。三売師定短部北自景訴層海全子相表。著漫寺対表前始稿殺法際込五新店広。': File name too long

Iecp实际上已尝试创建此文件,/tmp/tmp不允许文件名超过 255 字节。

此外,我还设法在鼠标垫(GTK 应用程序)中打开此文件,编辑并保存它 - 这一切都有效,这意味着 255 字节限制仅适用于某些 Linux 文件系统。

这并不意味着一切都会顺利。例如我最喜欢的控制台文件管理器 Midnight Commander,它是 Norton Commander 的克隆 -不能列表(显示文件大小为 0)、打开或对此文件执行任何操作:

Error
No such file or directory (2)

答案4

但我记得大多数Linux都支持NTFS,其最大文件名长度是255个UTF-16字符。

我们是在谈论文件名长度还是路径名长度?

NTFS 路径名的最大长度始终为 64K 字节(=32K UTF-16 代码点)。

Win32 API 施加了更严格的限制,因为(编辑评论)白痴程序员喜欢声明char filename[MAX_PATH],但周围存在语法混乱。

相关内容