SetFileValidData在做什么?与SetEndOfFile有什么区别?

时间:2012-09-01 13:11:51

标签: windows file

我寻找一种异步高效扩展文件的方法。

在支持文件Asynchronous Disk I/O Appears as Synchronous on Windows NT, Windows 2000, and Windows XP中说:

  

注意:应用程序可以进行前面提到的写操作   通过使用更改文件的有效数据长度来异步   SetFileValidData函数,然后发出WriteFile。

在MSDN中,SetFileValidDataSets the valid data length of the specified file的函数。

但我仍然不明白什么是“有效数据”,它与文件大小有什么区别?

我可以使用SetFilePointerExSetEndOfFile扩展文件大小,但SetFileValidData如何做到这一点?

SetFileValidData无法输入大于文件大小的参数。在这种情况下,SetFileValidData的生活意义是什么?

4 个答案:

答案 0 :(得分:24)

当您使用SetEndOfFile来增加文件的长度时,逻辑文件长度会更改并分配必要的磁盘空间,但实际上没有数据物理写入与新部分相对应的磁盘扇区文件。有效数据长度保持不变。

这意味着您可以使用SetEndOfFile非常快速地创建一个非常大的文件,如果您从文件的新部分读取,您将获得零。将实际数据写入文件的新部分时,有效数据长度会增加。

如果您只想保留空间,那就没关系,然后将按顺序将数据写入文件。但是如果你使文件非常大并立即在其末尾写入数据,则需要将零写入文件的新部分,这将花费很长时间。如果您实际上不需要该文件包含零,则可以使用SetFileValidData跳过此步骤;然后,该文件的新部分将包含先前删除的文件中的随机数据。

答案 1 :(得分:3)

请注意,setendoffile不会向磁盘上任何已分配的扇区写入任何零,它只是在MFT记录中分配空格指针,然后更新整个文件系统的空间位图。但操作系统或FS会在其MFT记录中记录有效/逻辑文件长度,如果你将它放大,从1GB到2GB,那么所附的1GB应该全为零,但FS不会将零写入磁盘,它请参阅此文件的有效长度以了解1GB应为零,如果您尝试读取此放大的1GB部分,它将直接在RAM中填充zeors,然后反馈给您的应用程序。但是如果您在1GB部分内写入任何字节的访问权限,则FS必须从原始1GB偏移量填充零到应用程序尝试写入的当前指针,而不是从当前位置到尾部的其他字节。同时记录有效/逻辑长度为0到当前位置,物理大小和分配大小仍为2GB。但是如果你使用setfilevaliddata,FS会直接将有效长度设置为2GB,并且不会费心填写任何零,无论你写什么位置,它只是写,但无论你读到什么位置,你都可以读出一些垃圾数据,这是由其他应用程序生成。

答案 2 :(得分:3)

同意Harry Johnston的回答,从实践的角度来看,虽然SetFileValidData具有性能优势,因为它不需要写零,但它确实具有安全隐患,因为该文件可能包含来自其他已删除文件的数据。因此,MSDN提到了一个特殊权限SE_MANAGE_VOLUME_NAME:http://msdn.microsoft.com/en-us/library/windows/desktop/aa365544(v=vs.85).aspx

原因是,如果正在运行的程序的用户帐户没有该权限,则使用SetFileValidData可以将其他用户的已删除数据公开到该特定文件的视图中,因此普通用户(非-administrators)不允许这样做。即使对于特权用户,他们仍然需要注意在文件系统中使用ACL(访问控制列表)来保护该文件,以便不与非特权用户共享。

答案 3 :(得分:-1)

似乎SenEndofFile并没有真正为目标文件分配保留磁盘空间,SetFileValidData负责这项工作。

Refered to MSDN

  

您可以使用SetFileValidData函数在非常特定的情况下创建大型文件,以便后续文件I / O的性能可以优于其他方法。具体来说,如果文件的扩展部分很大并且将被随机写入,例如在数据库类型的应用程序中,则扩展和写入文件所花费的时间将比使用SetEndOfFile并随机写入更快。

如果SetEndOfFile确实分配了空格,那么SetFileValidData在随机写作时不会比SetEndOfFile更好。所以SetEndOfFile可能只是创建一个带有孔的稀疏文件,而SetFileValidData可以进行实际分配。