3

这个问题是根据这个主题: 在c#中创建一个巨大的虚拟文件在几秒钟内

我刚刚检查了 xp/vista/seven 中的 fsutil.exe,将大量虚拟数据写入存储磁盘,与编程方式相比,写入如此大的文件所需的时间更少。

当我试图在.net 的帮助下做同样的事情时,它会比 fsutil.exe 花费更多的时间。

注意:我知道 .net 不使用本机代码,因为我刚刚使用本机 api 检查了这个问题,如下所示:

long int size = DiskFree('L' - 64);
const char* full = "fulldisk.dsk";
__try{
Application->ProcessMessages();
HANDLE hf = CreateFile(full,
                       GENERIC_WRITE,
                       0,
                       0,
                       CREATE_ALWAYS,
                       0,
                       0);
SetFilePointer(hf, size, 0, FILE_BEGIN);
SetEndOfFile(hf);
CloseHandle(hf);
}__finally{
    ShowMessage("Finished");
    exit(0);

答案与.net 结果一样。

但在 fsutil.exe 的帮助下,它只需要比上面更少的持续时间,或者 .net 方法说它快 2 倍

示例:使用 .net 写入 400mb 大约需要 40 秒,而使用 fsutil.exe 大约需要 20 秒或更短。

对此有什么解释吗?或者 fsutil.exe 使用的哪个函数具有这种重要的编写速度?

4

4 回答 4

5

我不知道 fsutil 到底在做什么,但我知道有两种方法可以写一个比你上面所做的更快的大文件(或者寻找你想要的长度并写一个零,它具有相同的结果)。

这些方法的问题在于,它们会在您进行写入时对文件进行零填充。

您可以通过以下任一方式避免零填充:

  1. 创建稀疏文件。大小标记在您想要的位置,但在您写入数据之前,数据实际上并不存在于磁盘上。未写入区域的所有读取都将返回零。
  2. 使用SetFileValidData函数设置有效数据长度,而无需先将文件归零。但是,由于潜在的安全问题,此命令需要提升权限。
于 2009-12-12T12:18:59.113 回答
2

我同意最后的评论。我正在尝试使用微过滤器驱动程序并在回调中捕获 IRP_MJ_WRITE IRP。当我从 cmd 行或 win32 应用程序创建或写入文件时,我可以看到写入下降。但是当我使用“fsutil file createnew ...”命令创建文件时,我看不到任何写入。我在 NTFS 卷上的 win2k8 r2 上看到了这种行为。而且我不认为(虽然不确定 100%)它也是一个稀疏文件。它可能是在 MFT 中设置大小属性而不分配任何集群。fsutil 会检查可用空间,因此如果文件大小大于磁盘上的可用空间,则会出现错误 1。

我还运行了将 FSCTL_GET_RETRIEVAL_POINTERS 发送到文件的程序,我得到了整个文件大小的一个范围。但我相信它正在获取所有数据

于 2011-07-13T19:51:08.307 回答
1

这可能是

  • 用汇编程序编写(原始的致盲速度)
  • 执行此操作的本机 C/C++ 代码
  • 可能是一个未记录的系统调用来执行此操作或一些在任何地方都没有记录的技巧。

以上三点可能有一个巨大的重要因素 - 当你考虑它时,当加载 .NET 代码时,它会被运行时 jit'ted(好吧,如果你有一台速度极快的机器,时间因素就不会被注意到- 在低端奔腾上,它会很明显,加载缓慢)。

它很可能是用 C/C++ 编写的。如果它是用汇编程序编写的,您可能会感到惊讶。

您可以自行检查 - 查看可执行文件的文件大小并将其与 .NET 的可执行文件进行比较。您可能会争辩说该文件是压缩的,我怀疑它会被压缩,因此倾向于排除这一点,微软不会走那么远,我认为压缩可执行文件业务。

希望这能回答你的问题,最好的问候,汤姆。

于 2009-12-12T12:12:14.133 回答
1

fsutil 仅在 NTFS 和 exFAT 上快速,在 FAT32、FAT16 上不快 这是因为某些文件系统具有“初始化大小”概念,因此支持快速文件初始化。这只是保留集群,但不会将它们归零,因为它在文件系统中指出没有数据写入文件并且有效读取都将返回 00 填充的缓冲区。

于 2010-08-25T18:31:18.720 回答