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

noj0wjuj  于 2023-05-22  发布在  其他
关注(0)|答案(1)|浏览(143)

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

plicqrtu

plicqrtu1#

“hFile参数值标识的文件指针不用于重叠的操作。”
是的。是这样。但不适用于所有I/O操作,而仅适用于读和写(以及其他几种),但不适用于SetFilePointer(NtSetInformationFileFilePositionInformation
首先-什么是 * 文件指针 *?查看FILE_OBJECT结构-CurrentByteOffset -指定文件偏移量(以字节为单位)的成员,与文件对象关联-在win32中称为 * 文件指针
注意,这个成员基本上由I/O管理器本身管理,而不是由(文件系统)驱动程序管理。
我们可以通过使用FilePositionInformation调用NtQueryInformationFileNtSetInformationFile来获取和设置这个成员
尽管这里指出:

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

这并不完全正确,即使打开的文件没有这个标志(即,与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设置),然后使用FileEndOfFileInformationFileAllocationInformation调用NtSetInformationFile(此调用仅用于优化)。
因此SetFilePointerSetEndOfFile将适用于任何文件。但效率不高。我建议永远不要使用SetFilePointer。对于具体的任务-简单地调用NtSetInformationFile(最好),或者如果你不喜欢ntapi -使用SetFileInformationByHandleFileEndOfFileInfo + FileAllocationInfo

FILE_END_OF_FILE_INFO eof = { * };
        SetFileInformationByHandle(hFile, FileEndOfFileInfo, &eof, sizeof(eof));
        SetFileInformationByHandle(hFile, FileAllocationInfo, &eof, sizeof(eof));

相关问题