2

我正在尝试通过 Windows 碎片整理 API(http://msdn.microsoft.com/en-us/library/aa363911 (VS.85 ).aspx)对单个文件进行碎片整理,但如果没有足够大的可用空间块供我使用文件 我想移动文件的其他部分以腾出空间。

链接的文章提到了其他文件的移动部分,但我找不到有关如何找出要移动的文件的任何信息。从可用空间位图中,我可以找到一个几乎足够大的空间,并且我知道它周围的逻辑簇号,但是从中我无法找出围绕它的文件,并且需要文件句柄来执行 FSCTL_MOVE_FILE 移动部分文件。

有没有什么办法,通过API或者通过解析MFT,找出一个逻辑簇号属于哪个文件,文件中哪个虚拟簇号对应于通过位图找到的逻辑簇号?

4

2 回答 2

2

缓慢但兼容的方法是递归扫描所有目录中的文件,并使用FSCTL_GET_RETRIEVAL_POINTERS。然后扫描生成的 VCN-LCN 映射以查找相关集群。

另一种选择是查询驱动器的 USN 日志以获取文件参考 ID,然后使用FSCT_GET_NTFS_FILE_RECORD获取 $MFT 文件记录。

我目前正在开发一个简单的 Defrag 程序(用 Java 编写),旨在将目录中的文件(例如大型游戏的所有文件)打包在一起,以减少加载时间和加载滞后。

我使用一种更快的方法来检索 NTFS 或 FAT32 驱动器上的文件映射。

我直接解析 $MFT 文件(格式有一些缺陷),或者 FAT32 文件分配表以及目录。

诀窍是使用 FileCreate 打开驱动器(例如“c:”)以进行完全共享的 GENERIC 读取。然后可以使用 FileRead 和 FileSeek 在字节粒度上读取生成的句柄。这仅适用于管理员模式(或提升)。

在 NTFS 上,$MFT 可能是碎片化的,从引导扇区信息中定位它有点棘手。我使用 C:\$MFT 文件上的 FSCTL_GET_RETRIEVAL_POINTERS 来获取它的集群。

在 FAT32 上,必须解析引导扇区以定位 FAT 表和包含根目录文件的簇。您需要解析目录条目并递归定位子目录的集群。

于 2010-09-05T20:43:30.747 回答
0

没有从块 # 映射到文件的 O(1) 方式。您需要遍历整个 MFT 以查找包含该块的文件。

当然,在实时系统中,一旦您读取了该数据,它就已经过时了,您必须为移动数据 FSCTL 中的故障做好准备。

于 2010-09-17T21:21:18.430 回答