1
mercury233 2021-12-08 10:12:01 +08:00
硬盘速度不够快而且文件系统不支持的情况下,获取文件夹大小是非常慢的
|
2
libook 2021-12-08 10:16:04 +08:00 4
因为文件夹本身没有大小,文件夹的大小取决于文件夹内的文件大小只和,如果有子文件夹,还要递归计算子文件夹内文件大小只和。
除非有一种文件系统可以对每一个层级的文件夹大小进行预结算,并缓存;否则当遇到包含很多文件的文件夹,实时计算大小将耗费大量的 IO 读取时间。 |
3
nevin47 2021-12-08 10:28:15 +08:00
引用一句前几年被用烂了的话:先问是不是,再问为什么
现在主流的几个文件系统,想获取目录大小是极容易的,但是想快速获取目录大小是 [极难] 其实就想一想一个树,你想从 root 搜索到某个特定节点,是有很多快速搜索方法的。但是你想从 root 去统计下面所有 leaf 的一个属性,那只能靠遍历了(除非文件系统 /树的 node 数据结构中,有一个向下结算的属性,而且要能实时更新) |
4
felixcode 2021-12-08 11:10:56 +08:00
为什么会认为是极容易实现呢,因为只需要显示一串数字?
|
5
3dwelcome 2021-12-08 11:28:27 +08:00
@mercury233
"硬盘速度不够快而且文件系统不支持的情况下,获取文件夹大小是非常慢的" 时代在进步,现在固态硬盘便宜,用的人很多。当然新硬盘,文件系统也可以用最新的。 那么为什么文件管理器还不支持?就是码农懒惰呗。 |
6
6IbA2bj5ip3tK49j 2021-12-08 11:30:04 +08:00
@3dwelcome 真是张口就来,你用“新文件系统”+“新硬盘”来写一个 demo 打打脸呗。
|
7
3dwelcome 2021-12-08 11:36:20 +08:00
|
8
pan20060802 2021-12-08 11:41:25 +08:00
穷
|
9
msg7086 2021-12-08 11:48:00 +08:00
文件夹大小很简单,文件夹内所有文件的大小很难。
不管他有没有用,不管他是否容易实现,速度跟不上就只能砍掉。 你想想看,现在文件大小还在用 1024 进制呢,为啥不用 1000 ?就因为当年做除 1000 的除法太慢了,比除 1024 慢不知道多少倍,所以这个功能就被砍掉了。 |
10
hand515 2021-12-08 11:55:49 +08:00
@3dwelcome #5
无论是操作系统,还是文件系统,都不会专门为固态硬盘设计。这种底层的东西要考虑泛用性( mac 除外) |
11
deplivesb 2021-12-08 12:29:46 +08:00
因为目录没有大小这一个说法,只有文件才有,而如果要想显示一个目录下所有文件的大小,就需要递归该目录以及所有子目录,这是一个极其耗时的 io 操作。
|
12
wanguorui123 2021-12-08 13:57:13 +08:00
1 ,文件夹递归很慢
2 ,文件夹记录大小实现起来比较麻烦,需要递归更新父文件夹和防止并发操作效率比较低 |
13
GrayXu 2021-12-08 15:08:50 +08:00
@3dwelcome 即使是固态盘,即时统计这个路径下海量小文件的开销也很大。本质上来说,就是普通的 ls 和统计文件夹大小两个操作对比,性能和使用频率都有显著 gap 。(换个角度想,就算作为一个统计量来维护,文件写和更新的开销也会显著增加。
|
14
kome 2021-12-08 15:30:20 +08:00 via iPhone
我统计了一下我 QQ 号对应的聊天记录文件夹的大小,36.9G ,92820 个文件,69807 个文件夹。耗时 30 秒(掐表)。文件夹大小一般不实时看,用不着增减文件就去统计,而且不像文件更改就更改了,也就改他一个;文件更改大小,数量,文件夹就去更改大小,开销太不划算了。咱也不缺那四五十秒一两分钟不是么。
|
15
cmdOptionKana 2021-12-08 15:53:48 +08:00
|
16
secondwtq 2021-12-08 16:15:15 +08:00 7
不要 assume“时代在进步”,很多东西不倒车已经是不错的了。
SSD 虽然快,但是不同 SSD 的速度也是参差不齐(特别是“便宜”的)。 软件就更别提了,放眼现在的主流文件系统,除了 APFS 之外,所有其他项目的底子都是上古时代的。APFS 倒是够“新”,所以 APFS 有个功能叫“Fast Directory Sizing”,可以直接从文件系统层获得文件夹的大小,不过就连这个好像也是需要手动启用,并且 Finder 自己也没有用上。 而且现在文件系统的痛点不是大文件,而是大量小文件。经过软件抽象后,SSD 把大量小文件操作的速度提升了 1-3 个数量级,但是还不够。我 du 了一下 home 目录下的几个大文件夹,大概需要的时间在 5s-30s 以内。Windows 下用 explorer 看 C:\Windows 文件夹属性,统计大小花了 2 分 15 秒,换了一台 Windows 需要大概 1 分钟。无论是十秒钟还是一分钟都不是 UI 上能接受的量级。当然这么巨大的文件夹是少数(虽然我每次打开 home 或者 C:\ 都会看到 ...),但是问题在于那么程序呐,就都不知道,自己就不可以预料,一个文件夹到底有多大,需要花多长时间,这是个 O(n) 而非 O(1) 的过程。 可以通过缓存把这个过程变成 O(1) 的,比如 Finder 会把算好的文件大小放到 .DS_Store 里面去,不过既然涉及缓存,就必然会涉及到缓存如何更新的问题,这已经被证明是计算机科学中两大最困难的问题之一。比如 Finder 就没有处理好(我也不指望它能处理好)——我现在能看到有很多里面有一堆文件的文件夹大小显示 "Zero byte",但是这个功能依然是我认为 Finder 是最好的文件管理器之一的最重要原因之一。Finder 并不是唯一一个可以直接显示文件夹大小的本地文件管理器,KDE 套件的 Konqueror 也可以,这货保持了 KDE 的一贯作风,把这个功能藏在了设置深处,但是它是有限制的,如果目录嵌套超过一定的层级就不会显示,而这个阈值可以调整,这倒也是 KDE 的一贯作风。至于 Konqueror 有没有缓存就不清楚了。Konqueror 还有很多有趣的设计,比如和上古时期的 Windows 一样,把文件管理器和浏览器放在一块,它的“收藏夹”菜单(虽然现在貌似流行叫“书签”,但是作为从上古 Windows 玩过来的我还是更喜欢“收藏夹”)既可以放 HTTP URL ,也可以放本地文件夹。可惜这东西现在好像已经基本是被抛弃的状态。还有个比较勉强的是 Midnight Commander ,这货是个 TUI 界面,选中文件夹按 <C-Space> 会现场计算大小并显示在 size 那一列里,多选可以批量做,但是切出去这个信息就没了。 Konqueror 我倒是一般不会用,我日常用的还是 Finder 和 Dolphin ,对比之下发现 Finder 这个功能不仅 bug 多,还有额外的一些代价——比如在访问 HDD (包括使用 HDD 的 NAS )时,由于 Finder 一直在试图统计文件夹大小(部分情况还会涉及到生成媒体预览图),而 HDD 现在作为仓库盘一般什么乱七八糟的东西都有,就会让 HDD 一直处于忙的状态,很吵,Dolphin 就十分安静。额外生成的 .DS_Store 文件也会有麻烦——做个 Git 仓库,打个压缩包之类的都会掺合进来( OS X 有个开关可以禁止在网络磁盘上生成 .DS_Store ,但是这不解决根本问题)。另外如果是个移动设备,统计文件夹大小占用的额外资源可能会增大耗电量。从这些角度来说,认为“始终统计文件夹大小”在现行软件栈中有百利而无一害的大概跟喜欢用 Electron 的是一种生物,不是蠢就是坏。 从另一个角度来说,统计文件夹大小真的是那么常用的需求么?对于服务器或者大多数命令行场景来说,一般不是,服务器要想干这个有 du 。如果按照现有体系,O(n) 遍历统计,就意味着你随手敲一个 ls ,就有一定机率需要等 10-20 秒,盲盒在 70 年代被提早发明了!如果把文件夹大小存在文件系统里,那每一次 IO 操作都会附带更新这个信息的开销,而如果这个信息只是偶尔使用,很明显不值得。所以为服务器设计的软件肯定不会考虑这个问题。这个东西在消费者那可能用处稍微多一点,但也不是那么多。要想看谁占磁盘多有 QDirStat 这样的专门软件,并不一定非要文件管理器或文件系统来兼职。一个好用的磁盘占用分析工具实现上可能会涉及到一些优化技巧,不是简单的递归遍历能解决的。作为一个 Linux 用户,从各方面平衡的角度来说,我还是更偏向于 Konqueror 那样的做法,成本大的功能默认不打开,打开之后可以自定义。 再往远处说,“文件”这个抽象,过时了!淘汰了!( https://zhihu.com/question/472997775 )上面的讨论已经很清楚了,“文件系统”以及 OS 的文件操作 API ,既需要处理少量大文件也需要处理大量小文件,既包含 sysfs ,也包含 RAM Disk ,Optane ,SSD ,还包含 HDD ,网络,和 5.25 寸软盘。而现在一般用户还有多少机会直接和“文件”打交道呢? iOS 从发布时就直接隔开了不同 App 的文件存储,用户在笔记软件里的“笔记”也是直接在相关的软件里面访问的,Office 现在也在往云端发展,小而美倒是好像能把聊天记录备份成文件,不过也不能直接看,而且相信我如果小而美有个网盘业务的话,大概不会允许你直接往本地备份。 抽象总是有代价的,专门的需求就需要抛开通用的抽象,用专用的工具解决,比如做 Web 服务器用的是数据库,不是直接把数据 write 到文件里面。 当然这是本地的问题,至于为啥云端的东西不给你看,那答案倒是很简单,因为这些产品和“小而美”的设计思路,精神内核都是高度一致的,都是把用户当 ... 比起这个,我觉得给 Finder 和 Explorer 加上分屏功能倒是更有用。 |
17
Michelangelono 2021-12-08 17:56:49 +08:00
Everything 是怎么做到那么快速度的?
|
18
amber0317 2021-12-08 18:02:07 +08:00 via Android
node_modules:你是不是小看我就
|
20
cccer 2021-12-08 20:08:03 +08:00
@Michelangelono Everything 在勾选计算文价夹大小,并且在冷启动时也不快,我这 Everything 每次冷启动都需要 5s 以上。
|
21
DOLLOR 2021-12-08 21:15:08 +08:00
测量一张椅子的重量很容易,但是要你测量大量重量不等的椅子的重量,你觉得“极容易”?
|
22
Buges 2021-12-08 21:22:43 +08:00 via Android
很简单,因为 IO 。大部分程序都是设计成最小化 IO ,获取目录大小需要大量 IO ,将其作为默认行为是极其不合适的。
|
23
kaneg 2021-12-08 22:17:20 +08:00
递归效率不高,看上去很简单的信息,一旦数据量上去,获取成本很高。
|
24
neilyoone 2021-12-08 22:59:50 +08:00
cd /path
du -sh * 这个命令就可以显示 每个目录的大小了 |
25
ferock 2021-12-08 23:11:51 +08:00 via iPhone
性能考虑
|
26
Osk 2021-12-08 23:12:57 +08:00
打开 C: 盘我的电脑就卡死了怎么办? 在线等, 挺急的.
|
27
inhzus 2021-12-08 23:25:17 +08:00 via iPhone
只要你能接受 ls 一下卡三四分钟,也不是不能做到啊
|
28
webshe11 2021-12-08 23:31:50 +08:00
至少目前还不太实用
某讯云 轻量服务器 实测: cd / time du -h -d 1 . 用时 20 秒 |
29
shintendo 2021-12-08 23:35:43 +08:00 1
|
30
masterclock 2021-12-08 23:45:19 +08:00
我有时通过 sshfs 打开文件夹,网速小于 1M ,这要是打开的时候算一下大小……
SSD 速度也不一定快啊,我的某个嵌入式设备,用的 SSD ,但是最大时钟才 100MHz 另外计算文件夹大小的话,文件的软链接怎么算?文件夹的软链接怎么算?成环了的链接怎么算?硬链接怎么算? |
31
icyalala 2021-12-09 00:00:32 +08:00
作为参考,手头最新款 MBP 1T SSD ,统计 Xcode.app 文件夹大小
Finder 首次计算 108 秒,105,974 文件 du -h 花费 15s DaisyDisk 和 Disk Space Analyzer Pro 都花费大约 8s |
32
justnull 2021-12-09 23:41:16 +08:00 via Android
这里提一句,如果是 windows 用户且需要分析目录大小(比如清理硬盘),WizTree 是很方便且快速的软件
|
33
shyangs 2021-12-13 17:10:29 +08:00
|