问题

为什么 Linux 系统删除文件那么快?

回答
好,咱们就聊聊为啥在 Linux 下删个文件,感觉跟按了快进键似的,嗖一下就没了。这可不是什么魔法,而是 Linux 文件系统设计的一项重要特性,背后有一套相当聪明的机制。

首先,得明白一个道理:文件系统不是直接把文件内容从硬盘上“擦除”掉的。硬盘那么大的容量,要是真这么干,哪怕是毫秒级的操作,累计起来也得花不少时间,特别是当你一次删几百个几千个文件的时候。Linux 的设计哲学之一就是效率,所以它选择了另一种更快速的方式来标记一个文件“不存在”了。

这事的关键在于两个东西:目录项 (Directory Entry) 和 索引节点 (Inode)。

咱们先说说目录项。你可以把目录理解成一个清单,里面记录着这个目录下所有文件的名字,以及它们分别对应着文件系统的哪个角落。这个“角落”就是通过一个叫做 inode 号来引用的。所以,当你创建一个文件时,其实是做了两件事:

1. 在对应的目录下,增加一个记录,内容是“文件名A”指向“inode 号X”。
2. 在文件系统的一个特殊区域(称为 inode table),为 inode 号X 分配一个条目,这个条目里面才真正存放着文件的元数据,比如所有者、权限、创建时间、修改时间,以及最关键的——文件数据在硬盘上的具体存放位置(数据块的地址列表)。

那么,删除一个文件的时候,Linux 系统到底做了什么?它其实相当“懒惰”且高效:

1. 从目录项中移除文件名和 inode 号的关联: 这是最快的一步。系统找到包含这个文件的目录,然后在这个目录的清单里,把“文件名A”指向“inode 号X”的那一行给抹掉。想象一下,你从一个文件列表里划掉一行字,这操作是不是瞬间就完成了?
2. 递减 inode 的引用计数: 每个 inode 都有一个“引用计数”,记录着有多少个目录项(或者硬链接)指向它。当从目录中移除文件名后,对应的 inode 的引用计数就会减一。
3. 检查引用计数: 如果这个引用计数减到零了,那就说明再也没有任何东西引用这个 inode 了,也就是说这个文件“彻底消失”了。这时候,系统才会执行真正的“释放”操作:
标记 inode 为未使用: 在 inode table 中,将这个 inode 标记为“可用”。
释放 inode 所占用的数据块: 系统会查看这个 inode 中记录的,所有文件数据所在的硬盘扇区(数据块)的地址列表。然后,它会把这些数据块也标记为“可用”,等待新的数据来覆盖。

你看,整个过程并没有立刻去擦除硬盘上那些实际存储文件内容的扇区。它只是做了两件事:从目录里把名字划掉,然后告诉系统“这个 inode 和它指向的数据块现在没用了,可以重用了”。这个“标记”和“抹掉名字”的操作,在速度上比真正去写入新的数据(覆盖原数据)要快得多得多。

这就是为什么 Linux 删除文件感觉那么快的原因。它是一种“延迟写入”或者说“标记可用”的策略,而不是立即执行擦除操作。文件数据块的内容还在硬盘上,直到它们被新的文件内容覆盖为止。所以,有时候如果你误删了文件,如果及时采取措施,还有可能找回来一部分数据,就是因为数据块还没被覆盖嘛。

对比一下,某些老旧或者设计思路不同的文件系统,可能会选择在删除时立刻将数据块标记为无效并尝试擦除,那自然会慢一些。而 Linux 采用的这种机制,在处理大量小文件或者频繁删除操作时,优势就非常明显了。这是一种在速度、资源利用和数据持久性之间取得平衡的优秀设计。

网友意见

user avatar

测试性能之前,需要明确几点:

1. 数据是真正更新到硬件上,而不是缓存里;
2. 真正的性能数据不应该大于硬件总线速度(比如总线带宽是1GB/s,测试出2GB/s的数据必然是测试方法有问题);
3. 文件系统性能数据应该指的是底层API数据,至少是命令行上,而不是图形界面的数据

Windows和Linux的一大区别就是缓存机制不同。

1. Windows的缓存是基于盘(分区的),Linux是整个操作系统有一套统一的缓存管理机制
2. Linux的缓存很大,/dev/shm一般情况下是系统内存的一半,Windows的缓存机制与Linux不同,每个分区的缓存通常在几十MB左右(WIN7时代数据,新版本不了解)。

下面是测试环节:

同样一款U盘,同样的PC,新盘格式化FAT32以后,把coreutils-8.31拷贝进去(46M,约3000个文件),在Windows 10命令行删除,需要33.24秒,在Linux 19.04上删除需要34.636秒,基本上差不多。所以,对于可移动设备,并且是关闭缓存的情况下,二者性能其实差不多。

但是在本地硬盘上(SSD):

1. Windows删除需要0.78秒,Linux只需要0.05秒
2. 首次从U盘复制到本地硬盘,Linux首轮复制过去大概需要几秒钟(<5秒),但第二轮复制只需要0.08秒,46/0.08=575MB/s,即使不考虑写放大,这个数值也超过了我这个入门级的SSD的写速度。
3. Linux在执行写操作(删除、复制)以后,执行一下sync,会有比较明显的延迟
4. Windows从U盘复制到本地,首轮复制需要7秒多,第二轮复制需要5秒
5. Windows图形界面删除文件很慢,每次都要先统计有多少个文件

所以可以得出一些结论:

1. Linux对于本地磁盘的写操作(删除、复制)并没有真正写到盘上,sync才是
2. Windows的文件系统缓存机制做的不好,比Linux性能差的多,尤其是小文件
3. Windows图形界面的开销更大

如果做一些破坏性测试(我不做这个实验了,太费机器,容易把机器搞死),比如删除一个比较庞大的代码树(Linux内核这种级别),执行一下rm -rf,返回以后马上掉电重启(不是软关机),你会发现刚才删的东西大多数都还在。而Windows的NTFS虽然删的慢,但一般情况下不会回滚很多数据。

所以,Windows文件系统性能确实做的不好,但Linux快并不一定是真的删除。

Windows文件系统慢是因为它的缓存机制设计的问题(这个机制也直接影响了Windows无法删除正在打开的文件),想了解的话,去读一下github上的fastfat源码,可以了解个大概。我个人理解是微软不会去改变这个机制,因为这套东西跟Windows内核绑定的太紧密,除非重新设计Windows,否则不太可能有巨大的优化。

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有