我可以在目录中放入多少个文件?

Kip*_*Kip 544 filesystems limit

我保存在一个目录中的文件数量是否重要?如果是这样,目录中有多少文件太多,文件太多会有什么影响?(这是在Linux服务器上.)

背景:我有一个相册网站,上传的每个图像都重命名为8位十六进制数字(例如a58f375c.jpg).这是为了避免文件名冲突(例如,如果上传了大量"IMG0001.JPG"文件).原始文件名和任何有用的元数据都存储在数据库中.现在,我在images目录中有大约1500个文件.这使得列出目录中的文件(通过FTP或SSH客户端)需要几秒钟.但我看不出它除此之外还有什么影响.特别是,对于向用户提供图像文件的速度似乎没有任何影响.

我想过通过制作16个子目录来减少图像数量:0-9和af.然后我会根据文件名的第一个十六进制数字将图像移动到子目录中.但我不确定是否有任何理由这样做,除了偶尔通过FTP/SSH列出目录.

ISW*_*ISW 708

FAT32:

  • 最大文件数:268,173,300
  • 每个目录的最大文件数:2 16  - 1(65,535)
  • 最大文件大小:2 GiB - 1没有LFS,4 GiB - 1有

NTFS:

  • 最大文件数:2 32  - 1(4,294,967,295)
  • 最大文件大小
    • 实施:2 44  - 2 6字节(16 TiB - 64 KiB)
    • 理论值:2 64  - 2 6字节(16 EiB - 64 KiB)
  • 最大卷大小
    • 实施:2 32  - 1个集群(256 TiB - 64 KiB)
    • 理论值:2 64  - 1个簇(1 YiB - 64 KiB)

ext2:

  • 最大文件数:10 18
  • 每个目录的最大文件数:~1.3×10 20(性能问题超过10,000)
  • 最大文件大小
    • 16 GiB(块大小为1 KiB)
    • 256 GiB(块大小为2 KiB)
    • 2 TiB(块大小为4 KiB)
    • 2 TiB(块大小为8 KiB)
  • 最大卷大小
    • 4 TiB(块大小为1 KiB)
    • 8 TiB(块大小为2 KiB)
    • 16 TiB(块大小为4 KiB)
    • 32 TiB(块大小为8 KiB)

ext3:

  • 最大文件数:min(volumeSize/2 13,numberOfBlocks)
  • 最大文件大小:与ext2相同
  • 最大卷大小:与ext2相同

ext4:

  • 最大文件数:2 32  - 1(4,294,967,295)
  • 每个目录的最大文件数:无限制
  • 最大文件大小:2 44  - 1个字节(16 TiB - 1)
  • 最大音量:2 48  - 1字节(256 TiB - 1)

  • 我假设这些是整个分区的最大文件数,而不是目录.因此,此信息对于该问题并不太有用,因为无论方法如何,都会有相同数量的文件(除非您将目录计为文件). (24认同)
  • 由于我们现在在2012年,我认为是时候明确表示ext4对子目录的数量没有任何限制.最大文件大小也增加到16 TB.此外,文件系统的总体大小可能高达1 EB = 1,048,576 TB. (18认同)
  • 硬文件系统限制不回答问题"*我在一个目录中保存了多少文件?*" (9认同)
  • 显然,ext3每个目录也有60,000个文件(或目录或链接)的限制.我发现了很难的方法. (7认同)
  • 老答案,我知道......但是当你写**EXT4** - *最大文件数:2³² - 1(4,294,967,295)*和*每个目录的最大文件数:无限制*你真的很困惑我因为2³² - 1!= "无限".我想我现在需要一杯咖啡.;)尽管如此+1 (7认同)
  • 请添加ext3(和ext2?)每个目录的限制为32k-2个子目录:http://en.wikipedia.org/wiki/Ext3 (3认同)
  • 我认为 ext4 per-directory 文件限制语句是不正确的。您可能会遇到目录索引限制。来源:https://access.redhat.com/solutions/29894。我现在正在写一篇关于它的博客文章......很快就会出现在 https://adammonsen.com/post/1555/ 上。如果有人想要,很高兴在下面添加另一个答案,但我看到已经有很多答案,所以也许最好通过使每个目录的 ext4 限制“视情况而定”来改进这个 [已接受] 答案。 (2认同)

小智 182

我在一个ext3目录中有超过800万个文件.libc中readdir()这是由使用的find,ls而且大部分在此线程讨论的其他方法,列出大的目录.

在这种情况下原因lsfind速度很慢的是,一次readdir()只能读取32K的目录条目,因此在慢速磁盘上,需要许多次读取才能列出目录.这个速度问题有一个解决方案.我在以下网址写了一篇非常详细的文章:http://www.olark.com/spw/2011/08/you-can-list-a-directory-with-8-million-files-but-not-with- LS /

关键点是:getdents()直接使用- http://www.kernel.org/doc/man-pages/online/pages/man2/getdents.2.html而不是基于libc的任何内容,readdir()因此您可以指定缓冲区从磁盘读取目录条目时的大小.

  • 有趣的读!我可以问一下你在一个目录中有8百万个文件的情况吗?哈哈 (6认同)
  • 使用“ls -U”有时会有所帮助(按目录顺序列出条目) - 它可能会在读取条目时写出条目(不需要等待首先加载整个目录)。 (2认同)

S..*_*S.. 60

我有一个包含88,914个文件的目录.像你自己一样,它用于存储缩略图和Linux服务器.

通过FTP或php函数列出的文件很慢,但是在显示文件时也会出现性能损失.例如www.website.com/thumbdir/gh3hg4h2b4h234b3h2.jpg的等待时间为200-400毫秒.作为另一个站点的比较,我在一个目录中有大约100个文件,在等待约40ms之后显示图像.

我已经给出了这个答案,因为大多数人刚刚写了目录搜索功能将如何执行,你不会在拇指文件夹上使用 - 只是静态显示文件,但是会对如何实际使用文件的性能感兴趣.

  • 这是唯一有用的答案.我们也有类似的经历.我们的限制是1.000文件,以减少备份问题(太多目录也减慢). (5认同)
  • 你在哪个文件系统放慢速度这么慢?例如,XFS应该能够轻松处理目录中的100,000个文件而不会出现明显的减速. (2认同)
  • 与大多数其他人的观点相矛盾,我想确认这个答案。我们的社交网络网站上有数十万张图像。为了提高性能,我们被迫拥有 100 个(或某些文件为 1000 个)子目录并将文件分发到其中(对于我们来说是 linux+ Apache 上的 ext3)。 (2认同)

Bar*_*ler 56

它取决于Linux服务器上使用的特定文件系统.现在默认是使用dir_index的ext3,这使得搜索大型目录的速度非常快.

所以速度不应该是一个问题,除了你已经注意到的那个,这是列表需要更长的时间.

一个目录中的文件总数有限制.我似乎记得它肯定能够处理32000个文件.

  • ext3中的一个目录中有大约32K*子目录*的限制,但OP正在讨论图像文件.启用Dir索引的ext3文件系统中的文件没有(实际?)限制. (22认同)
  • Gnome和KDE以蜗牛的速度加载大型目录,windows将缓存目录以使其合理.我喜欢Linux,但kde和gnome编写得很糟糕. (4认同)
  • 这个答案已经过时了,现在[默认是ext4](https://en.wikipedia.org/wiki/List_of_default_file_systems)。 (3认同)
  • “启用了 Dir Index 的 ext3 文件系统中的文件没有(实际?)限制” - 我刚刚用完了 4TB ext4 文件系统上启用了 `dir_index` 的目录中的文件空间。我的目录中有大约 1700 万个文件。答案是使用tune2fs打开“large_dir”。 (2认同)

Ste*_*Kuo 47

请记住,在Linux上,如果您的目录文件太多,则shell可能无法扩展通配符.我在Linux上托管的相册中存在此问题.它将所有已调整大小的图像存储在单个目录中.虽然文件系统可以处理许多文件,但shell不能.例:

-shell-3.00$ ls A*
-shell: /bin/ls: Argument list too long
Run Code Online (Sandbox Code Playgroud)

要么

-shell-3.00$ chmod 644 *jpg
-shell: /bin/chmod: Argument list too long
Run Code Online (Sandbox Code Playgroud)

  • @Steve,对这些情况使用find(1)和/或xargs(1).出于同样的原因,在脚本中使用这些工具而不是命令行扩展是个好主意. (33认同)
  • 这是一个好点,但对于挑剔,给出的理由是错误的.*Argument列表太长*不是shell的限制,而是系统的`exec`实现的限制.shell通常可以很好地扩展通配符 - 它是使用许多返回错误的参数调用`exec`. (6认同)
  • @Steve当文件夹中的文件数量增加时,您是否看到性能下降?或者没有关系? (3认同)

arm*_*ino 23

我现在正在研究类似的问题.我们有一个层次结构的目录结构,并使用图像ID作为文件名.例如,id=1234567放入的图像

..../45/67/1234567_<...>.jpg
Run Code Online (Sandbox Code Playgroud)

使用最后4位数来确定文件的去向.

使用几千个图像,您可以使用一级层次结构.我们的系统管理员建议在任何给定目录(ext3)中只有几千个文件用于效率/备份/他想到的任何其他原因.

  • 这是一个非常好的解决方案。如果您坚持 2 位数字细分,则目录的每一层直至文件最多将包含 100 个条目,而最底部的目录将只有 1 个文件。 (2认同)

T.J*_*der 17

为了它的价值,我只是在ext4文件系统上创建了一个目录,其中包含1,000,000个文件,然后通过Web服务器随机访问这些文件.我没有注意到访问那些(例如)那里只有10个文件的溢价.

这与我几年前这样做的经历截然不同ntfs.

  • @YvonHuynh:文件类型完全无关。无论如何,列出/跟踪文件的目录中的开销是相同的。 (3认同)

小智 12

我遇到的最大问题是32位系统.一旦你传递了一定数量,像'ls'这样的工具就会停止工作.

一旦通过该障碍,尝试对该目录执行任何操作都会成为一个大问题.


Jav*_*ier 6

它实际上取决于所使用的文件系统,还有一些标志.

例如,ext3可以有数千个文件; 但是在成千上万之后,它过去很慢.主要是在列出目录时,也是在打开单个文件时.几年前,它获得了"htree"选项,大大缩短了获取带有文件名的inode所需的时间.

就个人而言,我使用子目录将大多数级别保持在大约一千个左右的项目中.在您的情况下,我将创建256个目录,其中包含ID的两个最后十六进制数字.使用最后一位而不是第一位数字,这样就可以获得负载平衡.

  • 如果文件名完全是随机的,那么使用哪个数字无关紧要. (6认同)
  • 或使用文件名SHA-1摘要的前N个字节。 (2认同)

Spa*_*arr 6

如果实现目录分区方案所涉及的时间很少,我赞成它.第一次必须调试涉及通过控制台操作10000文件目录的问题时,您将理解.

例如,F-Spot将照片文件存储为YYYY\MM\DD\filename.ext,这意味着我必须处理的最大目录,而手动操作我的~20000照片集大约是800个文件.这也使得文件更容易从第三方应用程序中浏览.永远不要假设您的软件是唯一可以访问您的软件文件的东西.

  • 我做广告反对按日期分区,因为批量导入可能会在某个特定日期对文件进行集群. (6认同)

Mic*_*rdt 6

它绝对取决于文件系统.许多现代文件系统使用不错的数据结构来存储目录的内容,但是较旧的文件系统通常只是将条目添加到列表中,因此检索文件是O(n)操作.

即使文件系统做得正确,列出目录内容的程序仍然绝对可能搞乱并进行O(n ^ 2)排序,所以为了安全起见,我总是限制每个文件的数量目录不超过500.


Yes*_*ke. 5

问题归结为您将如何处理这些文件。

在 Windows 下,任何超过 2k 文件的目录在资源管理器中对我来说打开速度都很慢。如果它们都是图像文件,则超过 1k 的文件往往在缩略图视图中打开速度非常慢。

有一次,系统施加的限制是 32,767。现在它更高了,但即使是这样,在大多数情况下一次处理的文件也太多了。


dat*_*ess 5

ext3实际上确实具有目录大小限制,并且它们取决于文件系统的块大小。没有每个目录的“最大数量”的文件,而是每个目录的“用于存储文件条目的最大块的数量”。具体来说,目录本身的大小不能超过高度为3的b树,并且树的扇出取决于块大小。有关更多详细信息,请参见此链接。

https://www.mail-archive.com/cwelug@googlegroups.com/msg01944.html

最近,我在一个以2K块格式化的文件系统上被这个问题所困扰,warning: ext3_dx_add_entry: Directory index full!当我从另一个ext3文件系统复制时,该文件系统莫名其妙地得到了目录已满的内核消息。就我而言,只有480,000个文件的目录无法复制到目标位置。


mgu*_*utt 5

“取决于文件系统”
一些用户提到性能影响取决于使用的文件系统。当然。像 EXT3 这样的文件系统可能会很慢。但是,即使你使用EXT4或者XFS你不能阻止通过上市文件夹lsfind或通过像FTP外部连接会越来越慢的慢。

解决方案
我更喜欢与@armandino相同的方式。为此,我在 PHP 中使用这个小函数将 ID 转换为每个目录产生 1000 个文件的文件路径:

function dynamic_path($int) {
    // 1000 = 1000 files per dir
    // 10000 = 10000 files per dir
    // 2 = 100 dirs per dir
    // 3 = 1000 dirs per dir
    return implode('/', str_split(intval($int / 1000), 2)) . '/';
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您想使用字母数字字符,则可以使用第二个版本:

function dynamic_path2($str) {
    // 26 alpha + 10 num + 3 special chars (._-) = 39 combinations
    // -1 = 39^2 = 1521 files per dir
    // -2 = 39^3 = 59319 files per dir (if every combination exists)
    $left = substr($str, 0, -1);
    return implode('/', str_split($left ? $left : $str[0], 2)) . '/';
}
Run Code Online (Sandbox Code Playgroud)

结果:

<?php
$files = explode(',', '1.jpg,12.jpg,123.jpg,999.jpg,1000.jpg,1234.jpg,1999.jpg,2000.jpg,12345.jpg,123456.jpg,1234567.jpg,12345678.jpg,123456789.jpg');
foreach ($files as $file) {
    echo dynamic_path(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>

1/1.jpg
1/12.jpg
1/123.jpg
1/999.jpg
1/1000.jpg
2/1234.jpg
2/1999.jpg
2/2000.jpg
13/12345.jpg
12/4/123456.jpg
12/35/1234567.jpg
12/34/6/12345678.jpg
12/34/57/123456789.jpg

<?php
$files = array_merge($files, explode(',', 'a.jpg,b.jpg,ab.jpg,abc.jpg,ddd.jpg,af_ff.jpg,abcd.jpg,akkk.jpg,bf.ff.jpg,abc-de.jpg,abcdef.jpg,abcdefg.jpg,abcdefgh.jpg,abcdefghi.jpg'));
foreach ($files as $file) {
    echo dynamic_path2(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>

1/1.jpg
1/12.jpg
12/123.jpg
99/999.jpg
10/0/1000.jpg
12/3/1234.jpg
19/9/1999.jpg
20/0/2000.jpg
12/34/12345.jpg
12/34/5/123456.jpg
12/34/56/1234567.jpg
12/34/56/7/12345678.jpg
12/34/56/78/123456789.jpg
a/a.jpg
b/b.jpg
a/ab.jpg
ab/abc.jpg
dd/ddd.jpg
af/_f/af_ff.jpg
ab/c/abcd.jpg
ak/k/akkk.jpg
bf/.f/bf.ff.jpg
ab/c-/d/abc-de.jpg
ab/cd/e/abcdef.jpg
ab/cd/ef/abcdefg.jpg
ab/cd/ef/g/abcdefgh.jpg
ab/cd/ef/gh/abcdefghi.jpg
Run Code Online (Sandbox Code Playgroud)

正如您所看到的$int-version 每个文件夹包含多达 1000 个文件和多达 99 个目录,其中包含 1000 个文件和 99 个目录......

但不要忘记,许多目录会导致相同的性能问题!

最后,您应该考虑如何减少文件总数。根据您的目标,您可以使用 CSS 精灵组合多个小图像,如头像、图标、笑脸等,或者如果您使用许多小型非媒体文件,请考虑组合它们,例如以 JSON 格式。就我而言,我有数千个迷你缓存,最后我决定将它们组合成 10 个。


小智 5

上面的大多数答案都没有表明原始问题没有“一刀切”的答案。

在今天的环境中,我们拥有大量不同硬件和软件的组合——有些是 32 位的,有些是 64 位的,有些是尖端的,有些是经过验证的——可靠且永不改变。除此之外还有各种新旧硬件、新旧操作系统、不同的供应商(Windows、Unixes、Apple 等)以及无数的实用程序和服务器。随着硬件的改进和软件转换为 64 位兼容性,让这个非常庞大而复杂的世界的所有部分在快速变化的步伐中很好地发挥作用必然会有相当大的延迟。

恕我直言,没有一种方法可以解决问题。解决方案是研究各种可能性,然后通过反复试验找到最适合您特定需求的方法。每个用户必须确定什么对他们的系统有效,而不是使用千篇一律的方法。

例如,我有一个包含一些非常大的文件的媒体服务器。结果是只有大约 400 个文件填充 3 TB 驱动器。仅使用了 1% 的 inode,但使用了总空间的 95%。其他人,有很多较小的文件,可能会在它们接近填充空间之前用完 inode。(根据经验,在 ext4 文件系统上,每个文件/目录使用 1 个 inode。)虽然理论上一个目录中可能包含的文件总数几乎是无限的,但实用性决定了整体使用情况决定了实际单位,而不是只是文件系统功能。

我希望以上所有不同的答案都促进了思考和解决问题的能力,而不是给进步带来不可逾越的障碍。


Har*_*tor 5

我一直遇到同样的问题。试图在ext4的Ubuntu服务器中存储数百万个文件。结束了运行自己的基准测试。发现平面目录在使用更简单的同时性能更好:

基准

写了一篇文章

  • 欢迎提供解决方案的链接,但请确保您的答案在没有它的情况下也是有用的:[在链接周围添加上下文](//meta.stackexchange.com/a/8259/165483),这样您的其他用户就会知道它是什么是以及为什么它在那里,然后引用您链接到的页面中最相关的部分,以防目标页面不可用。[仅是链接的答案可能会被删除。](//stackoverflow.com/help/deleted-answers) (2认同)
  • 有趣的。我们发现,即使在 10,000 个文件之后,性能也会很快下降到无法使用的程度。我们决定将文件分成每个级别约 100 个子目录,以实现最佳性能。我想这个故事的寓意是始终根据自己的要求在自己的系统上为自己进行基准测试。 (2认同)
  • 读了这篇文章,我不明白结论。您在第一部分中得出“使用扁平结构”的结论。然后“我无法使用更多文件运行基准测试”(因此,这里没有真正的基准测试?)。最后,“坚持常识并使用深层目录结构”。另外,您可能想在绘图左侧的栏中写“ms”而不是“s”。 (2认同)