One article建议:“在调用SetEndOfFile之前必须调用SetFilePointer”,但SetFilePointer的文档明确指出:“由hFile参数的值标识的文件指针不用于重叠的读写操作。"。
SetEndOfFile
SetFilePointer
plicqrtu1#
“hFile参数值标识的文件指针不用于重叠的读和写操作。”是的。是这样。但不适用于所有I/O操作,而仅适用于读和写(以及其他几种),但不适用于SetFilePointer(NtSetInformationFile和FilePositionInformation)首先-什么是 * 文件指针 *?查看FILE_OBJECT结构-CurrentByteOffset -指定文件偏移量(以字节为单位)的成员,与文件对象关联-在win32中称为 * 文件指针注意,这个成员基本上由I/O管理器本身管理,而不是由(文件系统)驱动程序管理。我们可以通过使用FilePositionInformation调用NtQueryInformationFile和NtSetInformationFile来获取和设置这个成员尽管这里指出:
NtSetInformationFile
FilePositionInformation
FILE_OBJECT
NtQueryInformationFile
这并不完全正确,即使打开的文件没有这个标志(即,与FILE_FLAG_OVERLAPPED)-通常这工作(取决于drom驱动程序实现).简单地说,如果文件以同步方式打开-此操作由I/O管理器本身处理(甚至不调用驱动程序)。以防异步文件请求传递给驱动程序。文件系统驱动程序(fastfat、ntfs)也通过更新CurrentByteOffset来处理该请求。为什么要读/写?因为寻找这个API的签名-它有(可选的同步句柄)ByteOffset参数-如果它存在-它使用,否则它从FILE_OBJECT中的CurrentByteOffset获取。对于异步句柄-ByteOffset是强制参数-它必须始终不为0(或系统返回错误无效参数)-因此异步读/写I/O中的CurrentByteOffset从未使用。但这与NtSetInformationFile无关SetFilePointer是什么意思它使用FilePositionInformation调用NtSetInformationFile(实际上它也调用和NtQueryInformationFile)。SetEndOfFile是什么意思它首先使用FilePositionInformation调用NtQueryInformationFile-以获取CurrentByteOffset值(由SetFilePointer设置),然后使用FileEndOfFileInformation和FileAllocationInformation调用NtSetInformationFile(此调用仅用于优化)。因此SetFilePointer和SetEndOfFile将适用于任何文件。但效率不高。我建议永远不要使用SetFilePointer。对于具体的任务-简单地调用NtSetInformationFile(最好),或者如果你不喜欢ntapi -使用SetFileInformationByHandle和FileEndOfFileInfo + FileAllocationInfo
FILE_FLAG_OVERLAPPED
CurrentByteOffset
ByteOffset
FileEndOfFileInformation
FileAllocationInformation
SetFileInformationByHandle
FileEndOfFileInfo
FileAllocationInfo
FILE_END_OF_FILE_INFO eof = { * }; SetFileInformationByHandle(hFile, FileEndOfFileInfo, &eof, sizeof(eof)); SetFileInformationByHandle(hFile, FileAllocationInfo, &eof, sizeof(eof));
1条答案
按热度按时间plicqrtu1#
“hFile参数值标识的文件指针不用于重叠的读和写操作。”
是的。是这样。但不适用于所有I/O操作,而仅适用于读和写(以及其他几种),但不适用于SetFilePointer(
NtSetInformationFile
和FilePositionInformation
)首先-什么是 * 文件指针 *?查看
FILE_OBJECT
结构-CurrentByteOffset -指定文件偏移量(以字节为单位)的成员,与文件对象关联-在win32中称为 * 文件指针注意,这个成员基本上由I/O管理器本身管理,而不是由(文件系统)驱动程序管理。
我们可以通过使用
FilePositionInformation
调用NtQueryInformationFile
和NtSetInformationFile
来获取和设置这个成员尽管这里指出:
这并不完全正确,即使打开的文件没有这个标志(即,与
FILE_FLAG_OVERLAPPED
)-通常这工作(取决于drom驱动程序实现).简单地说,如果文件以同步方式打开-此操作由I/O管理器本身处理(甚至不调用驱动程序)。以防异步文件请求传递给驱动程序。文件系统驱动程序(fastfat、ntfs)也通过更新CurrentByteOffset
来处理该请求。为什么要读/写?因为寻找这个API的签名-它有(可选的同步句柄)
ByteOffset
参数-如果它存在-它使用,否则它从FILE_OBJECT
中的CurrentByteOffset
获取。对于异步句柄-ByteOffset
是强制参数-它必须始终不为0(或系统返回错误无效参数)-因此异步读/写I/O中的CurrentByteOffset
从未使用。但这与NtSetInformationFile
无关SetFilePointer
是什么意思它使用FilePositionInformation
调用NtSetInformationFile
(实际上它也调用和NtQueryInformationFile
)。SetEndOfFile
是什么意思它首先使用FilePositionInformation
调用NtQueryInformationFile
-以获取CurrentByteOffset
值(由SetFilePointer
设置),然后使用FileEndOfFileInformation
和FileAllocationInformation
调用NtSetInformationFile
(此调用仅用于优化)。因此
SetFilePointer
和SetEndOfFile
将适用于任何文件。但效率不高。我建议永远不要使用SetFilePointer
。对于具体的任务-简单地调用NtSetInformationFile
(最好),或者如果你不喜欢ntapi -使用SetFileInformationByHandle
和FileEndOfFileInfo
+FileAllocationInfo