众所周知,在 NTFS 中,我们将元数据存储在称为 MFT 记录的结构中(其中包含一些运行)。
这本书问下一个问题
短文件比长文件使用更多的 MFT 记录吗?
我认为答案是否定的——因为如果我们有一个文件,其元数据的大小超过一个 MFT 的大小,那么我们必须使用运行。还有其他建议吗?
答案是肯定的。
MFT记录(NT4以前4KB,现在1KB)包含文件属性(如文件名、安全信息、小文件数据等);其中一些属性可以是常驻的(= 属性头和属性数据都位于 MFT 记录中),或非常驻的(只有 attrbite 头在 MFT 中,属性数据存储在磁盘上的其他位置 - 例如,数据属性通常是非居民)。一些属性必须保持常驻——例如,文件名属性;一些属性可以是驻留的,也可以是非驻留的——例如,数据属性。
如果你有大文件,这意味着 MFT 记录只包含数据属性的属性头,但数据位于其他地方 - 所以即使文件很大,它也只使用一个 MFT 记录;另一方面,如果你有一个很小的文件,但是这个文件有更多的文件名(链接),NTFS 必须分配更多的 MFT 记录来容纳所有文件名属性,它可以跨越许多 MFT 记录(使用称为属性的特殊属性列表)。
通常,一个新创建的文件(还没有数据)将成为常驻文件。这意味着只要有足够的可用空间,任何新数据都将放在其 MFT 记录中。随着数据的增长并且不再适合可用的 MFT 记录空间,通过将数据移出 MFT 并进入集群块(并具有运行列表),数据将变为非驻留数据。一个文件是非常驻的,如果数据后来被缩小到一个或零字节,它将永远不会被恢复为常驻文件。
如果文件是sparse
类型的并且尚未写入数据,则较大的数据并不总是非驻留的。只要写入的数据可以放入其可用的 MFT 记录空间,您就可以拥有 1MB 大小的稀疏文件并且仍然驻留。
如果一个零字节文件有多个硬链接,它甚至可以使用多个 MFT 记录。在这种情况下,它的其他 MFT 记录存储剩余的硬链接名称。
如果一个小文件的属性列表太大而无法容纳在单个记录中,那么它可以使用更多的 MFT 记录。
当文件记录段中没有更多空间用于存储属性时,将分配额外的文件记录段并将其插入到称为属性列表的属性中的第一个(或基本)文件记录段中。属性列表指示可以找到与文件关联的每个属性的位置。这包括基本文件记录中的所有属性,但属性列表本身除外。有关详细信息,请参阅
ATTRIBUTE_LIST_ENTRY
。https://docs.microsoft.com/en-us/windows/desktop/devnotes/master-file-table
这方面的一个例子是当它有大量的ADS时。我创建了一个占用大部分 MFT 记录空间的文件(1000/1024 字节,如下所示)
PS D:\> fsutil file queryoptimizemetadata .\test.txt
File metadata optimization : None
Attribute list size : 0 (0)
File metadata space used : 1000 (0x3e8)
File metadata space allocated : 1024 (0x400)
File metadata space usage : 97%
File records count(s) : 1
Number of resident attribute(s) : 3
Number of nonresident attribute(s) : 8
Total number of attributes : 11
Total active file metadata optimization(s) : 0
Total pending file metadata optimization(s) : 0
在我添加另一个流之后,您可以看到分配的文件元数据空间已翻倍至 2048 字节,即 2 条记录,并且ATTRIBUTE_LIST
必须使用占用 448 字节
PS D:\> cat .\test.txt | Set-Content -path .\test.txt -Stream stream8
PS D:\> fsutil file queryoptimizemetadata .\test.txt
File metadata optimization : None
Attribute list size : 448 (0x1c0)
File metadata space used : 1624 (0x658)
File metadata space allocated : 2048 (0x800)
File metadata space usage : 79%
File records count(s) : 2
Number of resident attribute(s) : 4
Number of nonresident attribute(s) : 9
Total number of attributes : 13
Total active file metadata optimization(s) : 0
Total pending file metadata optimization(s) : 0
如果文件太碎片化(或稀疏文件中的孔太多)并且记录没有足够的空间来存储范围列表,也会发生这种情况。其他可能性是权限太复杂,或者像其他人提到的那样有多个硬链接
$ATTRIBUTE_LIST
如果文件:
- 有大量的硬链接(存在很多文件名属性)。
- 变得非常碎片化,因此数据运行溢出 MFT 记录。
- 具有复杂的安全描述符(不适用于 NTFS v3.0+)
- 有许多命名流,例如数据流。
https://flatcap.org/linux-ntfs/ntfs/attributes/attribute_list.html
更多信息可以在 NTFS $MFT 文件是否有子记录中找到?