Utk*_*tku 8 ls filesystems files
我想知道为什么一个空目录占用了 4096 字节的空间,我看到了这个问题。据说空间是按块分配的,因此新目录的大小是 4096 字节。
但是我很确定“普通”文件的分配也是分块完成的。至少在Windows 文件系统中是这样,我猜测它至少在 ext* 中必须相似。
现在据我所知,其他类型文件的大小列表,例如文件、符号链接等,都是根据实际大小完成的。因为当我创建一个空文件时,我看到的大小为 0。当键入几个字符时,我将 <字符数> 字节视为大小等。
所以我的问题是,虽然其他文件的分配也是分块完成的,为什么报告目录和文件大小的策略不同?
我认为这个问题已经足够清楚了,但显然不是。我将尝试在这里澄清这个问题。
1)我认为一个目录是:
我将尝试通过以下示例来解释我认为目录是什么。看完后,如果有不对的地方请告知。
假设我们有一个名为mydir
. 假设它包含 3 个文件,分别是:f0
,f1
和f2
. 假设每个文件的长度为 1 个字节。
现在,什么是mydir
?它是一个指向包含以下内容的 inode 的指针:字符串“f0”和f0
指向的 inode 编号。字符串“f1”和f1
指向的 inode 编号。和字符串“f2”和f2
指向的inode编号。(至少这是我认为的目录。如果我错了,请纠正我。)
现在可能有两种计算目录大小的方法:
1)计算mydir
指向的inode的大小。
2) 将内容mydir
指向的 inode 的大小相加。
尽管 1 更违反直觉,但我们假设它是正在使用的方法。(对于这个问题,哪个方法是实际使用的方法并不重要。)然后,mydir
计算的大小如下:
2 + 2 + 2 + 3 * <space_required_to_store_an_inode_number>
Run Code Online (Sandbox Code Playgroud)
2 是因为每个文件名的长度为 2 个字节。
2)问题:
现在的问题是:假设我认为目录是正确的,报告的大小mydir
应该远小于 4096,无论使用方法 1 还是方法 2 来计算其大小。
现在,你会说它报告 4096 字节的原因是因为分配是在块中完成的。因此,报告的大小那么大。
但是我会说:对于常规文件,分配也是以块为单位完成的。(请参阅thrig 的回答以供参考)但是,它们的尺寸以实际尺寸报告。(如果它们包含 1 个字符,则为 1 个字节,如果它们包含 2 个字符,则为 2 个字节等)
所以我的问题是,为什么报告目录大小的策略与报告常规文件大小的策略如此不同?
更多说明:
我们知道,为非空文件和空目录分配的初始块数都是 8 个块。(请参阅thrig 的回答)因此,即使为常规文件和目录分配了相同数量的块,为什么报告的目录大小要大得多?
mad*_*lao 12
我认为您感到困惑的原因是因为您不知道目录是什么。为此,让我们退后一步,检查 Unix 文件系统是如何工作的。
Unix 文件系统对磁盘上的数据寻址有几个不同的概念:
换句话说,一个“文件”实际上由三个不同的东西组成:
大多数时候,用户将文件想象为“与文件名关联的实体”的同义词——只有当您处理低级实体或文件/套接字 API 时,您才会想到 inode 或数据块。目录是那些低级实体之一。
您可能认为目录是包含一堆其他文件的文件。这只是对了一半。目录是将文件名映射到 inode 编号的文件。它不“包含”文件,而是指向文件名的指针。把它想象成一个包含如下条目的文本文件:
上面的条目称为目录条目。它们基本上是从文件名到 inode 编号的映射。目录是包含目录条目的特殊文件。
这当然是一种简化,但它解释了基本思想和其他目录怪异之处。
可是等等!奇怪的事情正在发生!
ls -ld somedirectory
始终显示文件大小为 4096,而ls -l somefile
显示文件的实际大小。为什么?
混淆点1:当我们说“尺寸”时,我们可以指两件事:
一般来说,这些不是同一个数字。尝试stat
在常规文件上运行,您会看到这种差异。
当文件系统创建一个非空文件时,它通常会急切地按组分配数据块。这是因为文件有任意快速增长和收缩的趋势。如果文件系统只根据需要分配尽可能多的数据块来表示文件,那么增长/收缩会更慢,碎片将是一个严重的问题。因此,在实践中,文件系统不必为小的更改不断重新分配空间。这意味着磁盘上可能有很多空间被文件“占用”但完全未使用。
文件系统如何处理所有这些未使用的空间?没有。直到感觉需要为止。如果你的文件系统优化器工具——可能是一个在后台运行的在线优化器,可能是你的 fsck 的一部分,可能是你的文件系统本身内置的——感觉像它,它可能会重新分配你的文件的数据块——移动使用过的块,释放未使用的块块等。
所以现在我们来看看常规文件和目录之间的区别:因为目录构成了文件系统的“骨干”,您希望它们可能需要经常访问或修改,因此应该进行优化。所以你根本不希望它们支离破碎。创建目录时,它们总是将所有数据块的大小最大化,即使它们只有这么多目录条目。这对于目录来说是可以的,因为与文件不同,目录的大小和增长率通常是有限的。
4096 报告的目录大小是存储在目录 inode 中的“文件大小”数字,而不是目录中的条目数。它不是一个固定的数字——它是适合目录分配的块数的最大字节数。通常,这是为具有任何内容的文件分配的 512 字节/块乘以 8 个块 - 顺便说一句,对于目录,文件大小和分配的大小是相同的。因为它是作为单个组分配的,所以文件系统优化器不会四处移动它的块。
随着目录的增长,更多的数据块被分配给它,并且它也会通过相应地调整文件大小来最大化这些块。
因此ls
,stat
将显示目录 inode 的文件大小字段,该字段设置为分配给它的数据块的大小。