欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-23 12:06:28
...

我在一个目录中保留多少个文件有关系吗? 如果是这样,那么目录中有多少文件太多了,文件太多会有什么影响? (这是在Linux服务器上。)

背景:我有一个相册网站,并且上传的每个图像都重命名为8位十六进制ID(例如a58f375c.jpg)。 这是为了避免文件名冲突(例如,如果上传了许多“ IMG0001.JPG”文件)。 原始文件名和任何有用的元数据都存储在数据库中。 现在,在images目录中大约有1500个文件。 这使得通过FTP或SSH客户端列出目录中的文件需要花费几秒钟的时间。 但是我看不到有什么其他效果。 特别是,对图像文件提供给用户的速度似乎没有任何影响。

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


#1楼

我有一个包含88,914个文件的目录。 像您一样,它用于在Linux服务器上存储缩略图。

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

我给出了这个答案,因为大多数人只是写了目录搜索功能的执行方式,您不会在thumb文件夹上使用它-只是静态地显示文件,但会对文件实际使用方式的性能感兴趣。


#2楼

我只需要在ext4文件系统上创建一个目录,其中包含1,000,000个文件,然后通过Web服务器随机访问这些文件即可。 我访问那里(例如)只有10个文件的文件并没有任何溢价。

这与几年前我在ntfs上进行此操作的经验完全不同。


#3楼

不是答案,而是一些建议。

选择一个更合适的FS(文件系统)。 从历史的角度来看,您的所有问题都非常明智,可以成为数十年来不断发展的FS的中心。 我的意思是,更现代的FS可以更好地支持您的问题。 首先根据FS清单的最终目的制作一个比较决策表。

我认为是时候改变您的范式了。 因此,我个人建议使用可识别分布式系统的FS ,这对大小,文件数等没有任何限制。否则,您迟早会遇到新的无法预料的问题。

我不确定是否可以工作,但是如果您不提及一些实验,请尝试使用当前文件系统上的AUFS。 我猜它具有将多个文件夹模拟为单个虚拟文件夹的功能。

要克服硬件限制,可以使用RAID-0。


#4楼

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

https://www.mail-archive.com/[email protected]/msg01944.html

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


#5楼

只要没有超出操作系统的限制,就没有一个数字“太多”。 但是,无论操作系统是什么,目录中的文件越多,访问任何单个文件所花费的时间就越长,并且在大多数操作系统上,性能是非线性的,因此从10​​,000个文件中查找一个文件所花费的时间长于10倍。然后找到1,000个文件。

与目录中包含大量文件相关的次要问题包括通配符扩展失败。 为了降低风险,您可以考虑按上传日期或其他有用的元数据顺序对目录进行排序。


#6楼

“取决于文件系统”
一些用户提到对性能的影响取决于所使用的文件系统。 当然。 像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)) . '/';
}

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

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)) . '/';
}

结果:

<?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

如您所见,对于$int -version,每个文件夹最多包含1000个文件和99个目录,其中包含1000个文件和99个目录...

但是请不要忘记,这会对许多目录造成相同的性能问题!

最后,您应该考虑如何减少文件总数。 根据您的目标,您可以使用CSS精灵来组合多个小图像,例如头像,图标,表情符号等。或者,如果您使用许多小的非媒体文件,请考虑以JSON格式进行组合。 以我为例,我有数千个小型缓存,最后我决定将它们组合成10个一包。


#7楼

上面大多数答案无法显示的是,原始问题没有“一刀切”的答案。

在当今的环境中,我们拥有由各种硬件和软件组成的大型企业集团-有些是32位的,有些是64位的,有些是尖端的,有些是经过实践检验的-可靠且永不改变。 除此之外,还有各种较新的硬件,较新的OS,不同的供应商(Windows,Unix,Apple等)以及大量实用程序和服务器。 随着硬件的改进和软件转换为64位兼容性,在使这个非常大而复杂的世界中的所有部分都能够顺应快速变化的步伐时,必须要有相当大的延迟。

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

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

我希望以上所有不同的答案能促进思想和问题的解决,而不是为进步提出不可逾越的障碍。


#8楼

我遇到了类似的问题。 我试图访问其中包含超过10,000个文件的目录。 构建文件列表并在任何文件上运行任何类型的命令都花费了太长时间。

我想出了一些PHP脚本来为自己完成此操作,并试图找到一种防止它在浏览器中超时的方法。

以下是我为解决该问题而编写的php脚本。

列出目录中包含FTP文件过多的文件

它如何帮助某人


#9楼

我遇到的最大问题是在32位系统上。 一旦传递了一定数量,“ ls”之类的工具就会停止工作。

一旦通过该障碍,尝试对该目录执行任何操作将成为一个巨大的问题。


#10楼

问题归结于您将如何处理文件。

在Windows下,任何文件超过2k的目录都倾向于在资源管理器中为我缓慢打开​​。 如果它们都是图像文件,则在缩略图视图中打开超过1k的速度会非常缓慢。

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


#11楼

这取决于Linux服务器上使用的特定文件系统。 如今,默认值为带有dir_index的ext3,这使得搜索大型目录变得非常快。

因此,除了您已经提到的速度之外,速度不应该成为问题,因为上市将需要更长的时间。

一个目录中的文件总数是有限制的。 我似乎记得它肯定可以处理32000个文件。


#12楼

它实际上取决于所使用的文件系统以及一些标志。

例如, ext3可以有成千上万个文件。 但是经过数千次之后,它过去的运行速度非常慢。 通常在列出目录时,但在打开单个文件时。 几年前,它获得了“ htree”选项,大大缩短了获得给定文件名的索引节点所需的时间。

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


#13楼

我记得运行一个在输出中创建大量文件的程序。 文件在每个目录中的排序为30000。 我不记得必须重用产生的输出时遇到任何读取问题。 它是在32位Ubuntu Linux笔记本电脑上,即使几秒钟后Nautilus仍显示目录内容。

ext3文件系统:在64位系统上,类似的代码可以很好地处理每个目录64000个文件。


#14楼

FAT32

  • 最大文件数:268,173,300
  • 每个目录文件的最大数目:2月16日至 1 (65535)
  • 最大文件大小:2 GiB-1(不带LFS) ,4 GiB-1(带LFS)

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)

#15楼

如果实现目录分区方案所花费的时间很少,那么我赞成这样做。 第一次调试涉及通过控制台操作10000文件目录的问题时,您将了解。

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


#16楼

请记住,在Linux上,如果目录中包含太多文件,则外壳程序可能无法扩展通配符。 我在Linux上托管的相册遇到此问题。 它将所有调整大小的图像存储在一个目录中。 虽然文件系统可以处理许多文件,但Shell无法。 例:

-shell-3.00$ ls A*
-shell: /bin/ls: Argument list too long

要么

-shell-3.00$ chmod 644 *jpg
-shell: /bin/chmod: Argument list too long

#17楼

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

即使文件系统做对了,列出目录内容的程序也绝对有可能弄乱并进行O(n ^ 2)排序,因此,为了安全起见,我总是会限制每个文件的数量。目录不超过500。


#18楼

我认为这不能完全回答您有多少个问题,但是解决长期问题的一个想法是,除了存储原始文件元数据之外,还要存储磁盘上存储的文件夹-规范化删除那部分元数据。 一旦文件夹的大小超出限制,无论是出于性能,美观还是其他原因,您都可以使用它,您只需创建第二个文件夹并开始将文件放到那里...


#19楼

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

..../45/67/1234567_<...>.jpg

使用最后4位数字确定文件的位置。

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


#20楼

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

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

写了一篇文章


#21楼

我在一个ext3目录中有超过800万个文件。 findls和此线程中讨论的大多数其他方法使用的libc readdir()列出大型目录。

在这种情况下, 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()因此,您可以在从磁盘读取目录条目时指定缓冲区大小。

相关标签: filesystems limit