TRUNCATE_EXISTING vs. OPEN_EXISTING+SetEndOFile
用TRUNCATE_EXISTING调用Windows的CreateFile并用OPEN_EXISTING调用它,然后再调用SetEndOfFile有什么区别?
前者被证明需要GENERIC_WRITE访问权限,如果我只要求FILE_WRITE_DATA,则CreateFile会失败,并显示ERROR_ACCESS_DENIED。
对于后者,FILE_WRITE_DATA就足够了,CreateFile和SetEndOfFile都成功。
1 2 3 4 5 6 | #define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE |\\ FILE_WRITE_DATA |\\ FILE_WRITE_ATTRIBUTES |\\ FILE_WRITE_EA |\\ FILE_APPEND_DATA |\\ SYNCHRONIZE) |
因此,除了
如果您为
但实际上,截断文件所需的全部是
对于将文件截断为零大小,我们可以使用或:
-
NtSetInformationFile 与FileEndOfFileInformation (
呼叫者必须已打开设置了FILE_WRITE_DATA 标志的文件
在DesiredAccess参数中)或
FileAllocationInformation -在所有窗口上均可使用 -
SetFileInformationByHandle -非常薄的win32 shell
NtSetInformationFile ,但仅可从Vista获得。与
FileEndOfFileInfo 或FileAllocationInfo 。请注意,如果我们设置
AllocationSize 设为0-文件也将被截断为0大小。The end-of-file (EOF) position for a file must always be less than or
equal to the file allocation size. If the allocation size is set to a
value that is less than EOF, the EOF position is automatically
adjusted to match the file allocation size. -
SetEndOfFile 首先调用ZwQueryInformationFile
FilePositionInformation (在打开文件句柄后将其设置为0)
然后使用它(FILE_POSITION_INFORMATION )两次通话
FileEndOfFileInformation 和FileEndOfFileInformation
FileAllocationInformation 。很明显,在这种情况下,我们有2个没有
需要额外调用内核。所以这效率不高先比较2
方法。 -
CreateFile 和TRUNCATE_EXISTING 的第一个打开文件,然后
设置FileAllocationInformation 调用NtSetInformationFile
设为0。但是,此调用方式(您如何查看)需要额外的访问权限-
FILE_GENERIC_WRITE 确实不需要。只需要
FILE_WRITE_DATA 。所以这样不好 -
将
NtCreateFile 与FILE_OVERWRITE 一起使用
CreateDisposition-在单个调用打开文件中并将EOF设置为0。通过意义TRUNCATE_EXISTING 必须执行此操作(使用FILE_OVERWRITE
处置)。但是由于未知的原因(我认为这是错误),它使用
FILE_OPEN 访问,并有额外的呼叫
NtSetInformationFile 与FileAllocationInformation -
如果我们不仅需要截断现有文件,还需要创建新文件
空文件(如果尚不存在)-最好使用FILE_OVERWRITE_IF
选项或与之对应的CREATE_ALWAYS -这也打开并
在对内核的单次调用中截断文件。或创建新文件