我可以在目录中放置多less个文件?
这与我在一个目录中保存多less个文件有关系吗? 如果是这样的话,目录中有多less文件太多了,文件太多会带来什么影响? (这是在Linux服务器上)
背景:我有一个相册网站,上传的每个图片都被重新命名为一个8位数字的ID(比如a58f375c.jpg)。 这是为了避免文件名冲突(例如,如果上传大量“IMG0001.JPG”文件)。 原始文件名和任何有用的元数据存储在数据库中。 现在,我在图像目录中有大约1500个文件。 这使得列出目录中的文件(通过FTP或SSH客户端)需要几秒钟。 但是除此之外,我看不出有什么影响。 尤其是,对于向用户提供图像文件的速度似乎没有任何影响。
我想过通过制作16个子目录来减less图像的数量:0-9和af。 然后,我会根据文件名的第一个hex数字是什么,将图像移动到子目录中。 但是我不确定除了通过FTP / SSH偶尔列出目录之外,还有什么理由这样做。
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簇
ext2 :
- 最大文件数量:10 18
- 每个目录的最大文件数量:〜1.3×10 20 (性能问题超过10,000)
- 最大文件大小
- 16 GiB(块大小1 KiB)
- 256 GiB(块大小2 KiB)
- 2 TiB(块大小4 KiB)
- 2个TiB(8个块的块大小)
- 最大卷大小
- 4个TiB(块大小1 KiB)
- 8个TiB(块大小2 KiB)
- 16个TiB(块大小4 KiB)
- 32个TiB(8个块的块大小)
ext3 :
- 最大文件数量:最小(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)
我在一个ext3目录中有超过800万个文件。 libc readdir()
被find
, ls
和这个线程中讨论的大多数其他方法用于列出大型目录。
在这种情况下, ls
和find
的原因是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()
所以您可以在从磁盘读取目录条目时指定缓冲区大小。
这取决于Linux服务器上正在使用的特定文件系统。 现在缺省是ext3 dir_index,这使得search大目录非常快。
所以速度不应该是一个问题,除了你已经注意到,这是上市将需要更长的时间。
一个目录中的文件总数是有限制的。 我似乎记得它绝对工作达32000个文件。
我有一个88,914个文件的目录。 就像你自己一样,这是用来存储缩略图,并在Linux服务器上。
通过FTP或PHPfunction列出的文件是缓慢的,但也有性能影响显示文件。 例如www.website.com/thumbdir/gh3hg4h2b4h234b3h2.jpg有200-400毫秒的等待时间。 作为另一个网站上的比较,我有一个目录中的约100个文件,图像显示后,只有约40毫秒的等待。
我已经给出了这个答案,因为大多数人已经写了如何执行目录searchfunction,你不会在一个拇指文件夹上使用 – 只是静态显示文件,但会对如何实际使用文件。
请记住,在Linux上,如果文件太多,目录可能无法扩展通配符。 我有一个在Linux上托pipe的相册的问题。 它将所有resize的图像存储在一个目录中。 虽然文件系统可以处理很多文件,但是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
我现在正在处理类似的问题。 我们有一个hierarchychal目录结构,并使用图像ID作为文件名。 例如, id=1234567
的图像被放入
..../45/67/1234567_<...>.jpg
使用最后4位数字来确定文件的位置。
有了几千张图片,您可以使用一个层次的层次结构。 我们的系统pipe理员在任何给定的目录(ext3)中都提供了不超过几千个文件来提高效率/备份/无论他考虑到什么其他原因。
对于它的价值,我只是在ext4
文件系统上创build了一个目录,里面有1,000,000个文件,然后通过networking服务器随机访问这些文件。 我没有注意到访问那些在那里只有10个文件(说)的任何溢价。
这与我在几年前在ntfs
上做这件事的经历截然不同 。
我遇到的最大问题是在32位系统上。 一旦你通过了一定数量的工具,像'ls'就停止工作了。
一旦你通过这个障碍试图做任何与该目录,成为一个巨大的问题。
这真的取决于使用的文件系统,还有一些标志。
例如, ext3可以有数千个文件; 但几千后,它以前非常缓慢。 大多时候列出一个目录,而且在打开单个文件的时候。 几年前,它获得了“htree”选项,大大缩短了索引到文件名所需的时间。
就我个人而言,我使用子目录来保存大部分级别的项目。 在你的情况下,我会创build256个目录,ID的两个最后的hex数字。 使用最后一个数字,而不是第一个数字,所以你得到负载平衡。
这绝对取决于文件系统。 许多现代文件系统使用体面的数据结构来存储目录的内容,但是较老的文件系统通常只是将条目添加到列表中,所以检索文件是O(n)操作。
即使文件系统是正确的,对于列出目录内容的程序来说,仍然是绝对可能的,并且进行O(n ^ 2)sorting,所以为了安全起见,我总是限制每个文件的数量目录不超过500个。
这个问题归结为你将要处理的文件。
在Windows下,任何超过2k文件的目录都会在资源pipe理器中缓慢打开。 如果他们都是图像文件,超过1k倾向于在缩略图视图中缓慢打开。
有一次,系统强加的限制是32,767。 现在比较高,但是在大多数情况下,即使是一次处理太多的文件也是如此。
如果实现目录分区scheme的时间很less,我赞成。 第一次你必须debugging一个涉及通过控制台操作一个10000文件目录的问题,你会明白的。
例如,F-Spot将照片文件存储为YYYY \ MM \ DD \ filename.ext,这意味着手动操作我的~20000-photo集合时,我必须处理的最大目录大约有800个文件。 这也使得文件更容易从第三方应用程序浏览。 永远不要以为你的软件是唯一能访问你软件文件的东西。
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个文件的目录无法被复制到目的地。
我记得运行一个程序,在输出中创build了大量的文件。 这些文件按每个目录30000sorting。 当我不得不重新使用生成的输出时,我不记得有任何读取的问题。 这是在一个32位的Ubuntu Linux笔记本电脑,甚至Nautilus显示目录的内容,虽然几秒钟后。
ext3文件系统:在64位系统上的类似代码可以很好地处理每个目录64000个文件。
我尊重这个并不完全回答你的问题,关于多less是太多了,但解决长期问题的一个想法是,除了存储原始文件的元数据,还存储磁盘上存储在哪个文件夹 – 正常化出这个元数据。 一旦文件夹增长超过一定的限制,你对性能,审美或其他原因感到满意,你只需创build第二个文件夹,并开始删除文件…
我遇到了类似的问题。 我试图访问一个超过10,000个文件的目录。 构build文件列表并在任何文件上运行任何types的命令花费的时间太长。
我想了一个小小的PHP脚本来为自己做这件事,并试图find一种方法来防止在浏览器中超时。
以下是我写的解决这个问题的PHP脚本。
列出FTP文件太多的文件
它如何帮助某人
我更喜欢@armandino相同的方式。 为此,我在PHP中使用这个小函数将ID转换成每个目录1000个文件的文件path:
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个目录的目录…
但是不要忘记,对于许多目录可以减慢你的备份过程。 如果你想通过文件读取目录文件(ftp客户端,文件读取function等),可以自由地testing每个目录1000到10000个文件,但不要添加更多,因为你将有很长的访问时间。
最后你应该考虑如何减less文件总数。 根据您的目标,您可以使用CSS精灵组合多个小图像,如头像,图标,表情符号等,或者如果您使用许多小型的非媒体文件考虑结合他们,例如JSON格式。 在我的情况下,我有数以千计的迷你caching,最后我决定把它们组合成10个。
不是一个答案,但只是一些build议。
select一个更合适的FS(文件系统)。 既然从历史的angular度来看,你们所有的问题都足够明智,几十年来一直是FSs的核心。 我的意思是更现代的FS更好地支持你的问题。 首先根据您的FS列表的最终目的制定比较决策表。
我认为是时候改变你的范式了。 所以我个人build议使用一个分布式系统感知的FS ,这意味着在大小,文件数量等方面没有任何限制。否则,你迟早会面临新的意想不到的问题。
我不确定是否可以工作,但是如果你没有提到一些实验,那就试试AUFS在当前的文件系统上。 我想它有设备来模拟多个文件夹作为一个单一的虚拟文件夹。
要克服硬件限制,可以使用RAID-0。
没有一个“太多”的数字,只要不超过操作系统的限制。 但是,无论操作系统如何,目录中的文件越多,访问任何单个文件所需的时间就越长,而在大多数操作系统中,性能是非线性的,因此要find10,000个文件中的一个文件需要多于10倍然后在1000中find一个文件。
与目录中有大量文件相关的次要问题包括通配符扩展失败。 为了降低风险,您可以考虑按照上传date或其他一些有用的元数据来订购目录。
以上大部分答案未能表明的是,对于原来的问题,没有“One Size Fits All”的答案。
在当今的环境中,我们拥有一个不同硬件和软件的大型集团 – 有些是32位的,有些是64位的,有的是尖端的,有的是真实可靠的,有的是永远不变的。 除此之外,还有各种旧式和新式硬件,新旧操作系统,不同厂商(Windows,Unix,Apple等)以及大量的公用事业和服务器。 随着硬件的改进和软件被转换为64位的兼容性,这个庞大而复杂的世界中的所有部分都随着变化的快速变化而发生很好的延迟。
恕我直言,没有办法解决一个问题。 解决的办法是研究可能性,然后通过反复试验找出最适合您特定需求的方法。 每个用户必须确定什么适用于他们的系统,而不是使用千篇一律的方法。
例如,我有一个媒体服务器几个非常大的文件。 结果只有大约400个文件填满3TB驱动器。 只有1%的节点被使用,但占总空间的95%。 其他人,有很多较小的文件可能会耗尽inode之前,他们接近填补空间。 (在ext4文件系统中,作为一个经验法则,每个文件/目录使用1个inode)。理论上,目录中可能包含的文件总数几乎是无限的,实用性决定了总体使用率决定了现实单位,而不是只是文件系统function。
我希望上述所有不同的答案都能促进思想和解决问题,而不是提出一个难以逾越的障碍。