【问题标题】:FSCTL_MOVE_FILE on Windows XP, System volume, FAT32Windows XP 上的 FSCTL_MOVE_FILE,系统卷,FAT32
【发布时间】:2012-11-29 18:07:12
【问题描述】:

我在对 windows xp、fat32 系统卷上的文件进行碎片整理时遇到问题。我不是在编写碎片整理程序,而是解决方案的一部分需要在磁盘上连续布置一组文件。为了确保这一点,我使用 FSCTL_MOVE_FILE ioctl 将文件扩展区移动到卷上足够大小的单个可用空间扩展区。流程如下:

1) 创建文件:

return m_file.Create(path,
                     GENERIC_READ | GENERIC_WRITE,
                     0, NULL,
                     CREATE_ALWAYS,
                     FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH |
                     FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
                     NULL);

2) 用零填充文件。

3) 检查文件是否有碎片,如果有,用FSCTL_GET_VOLUME_BITMAP获取卷位图,找到足够大小的空闲簇链。

4) 使用 FSCTL_MOVE_FILE 将文件碎片整理到找到的范围内:

MOVE_FILE_DATA input;
input.FileHandle = fileHandle;
input.StartingVcn.QuadPart = 0;
input.StartingLcn.QuadPart = freeExtent.lcn;
input.ClusterCount = totalFileClusters;

DWORD bytesReturned = 0; // unused

::DeviceIoControl(
        volumeHandle,
        FSCTL_MOVE_FILE,
        &input,
        sizeof(input),
        NULL,
        0,
        &bytesReturned,
        NULL);

最后一次调用在 NTFS 系统和常规卷上运行良好。 XP 上的非系统卷也没有问题。然而,在 XP 上的 FAT32 系统卷上,我几乎总是收到 INVALID_ARGUMENT (87) 错误。文件很大,大约700MB。该卷有大约 10GB 的可用空间。 fsctl 失败后,可以看到文件的一部分实际上在错误发生之前被移动了。我尝试了几次,但到目前为止,所有 50 次都失败了。我知道以这种方式移动大文件可能会失败,因为之前空闲的集群被卷上的其他东西占用,特别是如果卷有很多活动(就像系统卷通常有)。但是我不知道如何减轻这种情况,因为我没有内核存在。我做错了什么和/或我怎样才能做得更好?

【问题讨论】:

    标签: windows-xp fat32 defragmentation


    【解决方案1】:

    这里的简短回答是否定的,您无法从用户模式到达那里。您将始终与操作文件系统的其他应用程序/操作系统进程竞争。

    如果你真的想走这条路,你将需要编写一个相当复杂的内核驱动程序(文件系统微过滤器)来帮助同步这个操作。这可能会变得很棘手,特别是对于托管页面/交换文件的卷上的移动。

    祝你好运!

    【讨论】:

      【解决方案2】:

      两个问题。首先,在实时系统上,您总是与其他活动竞争(正如前面的回答者所建议的那样)。例如,一旦您检索了卷位图,它可能由于您看不到的其他进程中的操作而已经过时。

      其次,FAT32 可能对您一次可以移动的数量有限制。也许您应该考虑以 256Kb 的块(又名缓存管理器映射视图大小)移动文件。 如果您遇到错误,例如点击了以前空闲的空间,那么您需要做的工作就更少了。

      最后,如果你有一个 700Mb 的文件,如果它存在于 700 个 1Mb 的块中,我怀疑你会看到比单个 700Mb 块有任何显着的性能改进。

      【讨论】:

        猜你喜欢
        • 2011-06-19
        • 1970-01-01
        • 2012-12-05
        • 2013-08-13
        • 1970-01-01
        • 2019-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多