如何设置使用 FILE_FLAG_OVERLAPPED 打开的文件的大小?

问题描述 投票:0回答:1

一篇文章建议:“在调用

SetFilePointer
之前必须先调用
SetEndOfFile
”,但是
SetFilePointer
的文档明确指出:“由 hFile 参数的值标识的文件指针不用于重叠读写操作。”。

编辑:我用

FILE_FLAG_OVERLAPPED
打开了一个文件,对 4MB 进行了
SetFilePointer
操作,并调用了
SetEndOfFile
。然后,我将
SetFilePointer
FILE_BEGIN
中删除为零字节,然后将
OVERLAPPED
结构的
Offset
OffsetHigh
标志设置为
0xFFFFFFFF
写入它。写入发生在文件末尾,即从 4MB 标记开始。

c file winapi io
1个回答
2
投票

“由hFile的值标识的文件指针 参数不用于重叠的 readwrite 操作。”

是的。这是对的。但不适用于所有 I/O 操作,而仅适用于读和写(以及其他几个),但不适用于 SetFilePointer(

NtSetInformationFile
FilePositionInformation

首先 - 什么是文件指针?查看

FILE_OBJECT
结构 - CurrentByteOffset - 指定与文件对象关联的文件偏移量(以字节为单位)的成员 - 以及 win32 中所谓的 文件指针

注意,该成员基本上由 I/O 管理器本身管理,而不是由(文件系统)驱动程序管理。

我们可以通过调用

NtQueryInformationFile

NtSetInformationFile
FilePositionInformation
来获取和设置该成员

尽管这里指出:

调用者必须使用 CreateOptions 中指定的 FILE_SYNCHRONOUS_IO_ALERT 或 FILE_SYNCHRONOUS_IO_NONALERT 标志打开文件 参数。

这并不完全正确,即使文件在没有此标志的情况下打开(即使用

FILE_FLAG_OVERLAPPED

 ) - 通常可以这样做(取决于 drom 驱动程序实现)。简单地说,如果文件作为同步打开 - 此操作由 I/O 管理器本身处理(甚至不调用驱动程序)。如果是异步文件 - 请求传递给驱动程序。文件系统驱动程序(fastfat、ntfs)也通过更新来处理此请求
CurrentByteOffset

为什么要这样读/写?因为要查找此 api 的签名 - 它具有(同步句柄可选)

ByteOffset

 参数 - 如果存在 - 它会使用,否则它取自 
CurrentByteOffset
 中的 
FILE_OBJECT
。对于异步句柄 - 
ByteOffset
 是强制参数 - 它始终不能为 0(或系统返回错误无效参数) - 因此 
CurrentByteOffset
 在异步读/写 I/O 中从未使用过。但这与
NtSetInformationFile
无关

SetFilePointer

 是什么?它用 
NtSetInformationFile
 调用 
FilePositionInformation
 (实际上它也调用 和 
NtQueryInformationFile
)。

SetEndOfFile

 是什么?它首先使用 
NtQueryInformationFile
 调用 
FilePositionInformation
 - 获取 
CurrentByteOffset
 的值(由 
SetFilePointer
 设置),然后使用 
NtSetInformationFile
FileEndOfFileInformation
 调用 
FileAllocationInformation
(此调用仅是优化)。

所以

SetFilePointer

SetEndOfFile
 适用于任何文件。但效率不高。我建议根本不要使用
SetFilePointer
。对于具体任务 - 只需调用 
NtSetInformationFile
 (最好的),或者如果您不喜欢 ntapi - 使用 
SetFileInformationByHandle
FileEndOfFileInfo
 + 
FileAllocationInfo

FILE_END_OF_FILE_INFO eof = { * }; SetFileInformationByHandle(hFile, FileEndOfFileInfo, &eof, sizeof(eof)); SetFileInformationByHandle(hFile, FileAllocationInfo, &eof, sizeof(eof));
    
© www.soinside.com 2019 - 2024. All rights reserved.