为什么fsutil.exe花费的时间比通过编程方式将大文件写入磁盘的时间更less?

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

我只是检查了xp / vista / 7中的fsutil.exe,将大量的虚拟数据写入存储磁盘,与编程方式相比,编写这样一个大文件花费的时间更less。

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

注意:我知道.net不使用本机代码bcuz,我只是检查了这个问题与本地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的帮助下,它的持续时间只比上面的要less,或者.net的方法说它是2倍的速度。例如:用.net写入400mb将需要40秒的时间,而fsutil.exe需要花费20秒左右或更less。

有什么解释吗? 或fsutil.exe使用哪个function,这有什么意义的速度写?

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

这些方法的问题在于,在写入时它们会填满文件。

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

  1. 创建一个稀疏文件。 大小被标记在你想要的地方,但是直到你写下这个数据,这些数据实际上并不存在于磁盘上。 所有未读区域的读取将返回零。
  2. 使用SetFileValidData函数设置有效的数据长度,而不用先调零文件。 但是,由于潜在的安全问题,该命令需要提升权限。

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

我也运行FSCTL_GET_RETRIEVAL_POINTERS到程序sening文件,我得到了整个文件大小的一个范围。 但我相信这是获取所有数据

这是可能的

  • 写在汇编(原始盲目的速度)
  • 一个本地的C / C ++代码来做到这一点
  • 可能是一个没有记录的系统调用来做到这一点,或者一些没有记录在任何地方的技巧。

以上三点可能有一个巨大的重要因素 – 当你想到它,当一个.NET代码被加载时,它会被运行时抖动(好吧,如果你有一个快速的机器,时间因素不会引人注意 – 在一个低端的奔腾,这将是显而易见的,加载迟缓)。

它可能是用C / C ++编写的。 如果它是用汇编语言编写的,可能会让你感到惊讶。

你可以自己检查一下 – 查看可执行文件的大小,并将其与.NET的可执行文件进行比较。 你可能会争辩说,这个文件是压缩的,我怀疑它会是什么,所以倾向于排除这一点,微软不会那么做,我认为压缩的可执行文件业务。

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

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