如何使用ReadFile
函数和C ++
我使用了这段代码,但它读取了文件的前100个字节
我想读第二个100字节
hndl = CreateFileW(L"1.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SetFilePointer(hndl, 100, NULL, FILE_BEGIN);
ReadFile(hndl, pbytReadBuffer, 100, NULL, &ol);
答案 0 :(得分:4)
ReadFile API提供两种不同的方法来设置同步I / O时的起始偏移量:
您的代码失败是因为您正在设置隐式存储的文件指针,但随后(可能)传递零初始化OVERLAPPED
结构,忽略文件指针(有关详细信息,请参阅Synchronization and File Position)。
以下任一解决方案均可使用。首先,通过使用隐式存储的文件指针。当您想要在连续调用中读取文件块时,这很有用:
hndl = CreateFileW(L"1.txt", GENERIC_READ, 0, nullptr,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
// Move the file pointer to offset 100
SetFilePointer(hndl, 100, NULL, FILE_BEGIN);
// Read contents from the current offset
DWORD dwBytesRead{0};
ReadFile(hndl, pbytReadBuffer, 100, &dwBytesRead, nullptr);
或者,您可以传递OVERLAPPED
结构来传递偏移量。这忽略了隐式存储的文件指针。它的效率稍高,因为它不需要对文件I / O API进行两次调用。
hndl = CreateFileW(L"1.txt", GENERIC_READ, 0, nullptr,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
OVERLAPPED ol{};
// Set the offset from the start of the file
ol.Offset = 100;
ReadFile(hndl, pbytReadBuffer, 100, nullptr, &ol);
请注意,为简洁起见,这些样本中省略了错误处理。在实际代码中,您始终必须检查错误。
答案 1 :(得分:-1)
你需要像这样的代码
HANDLE hFile = CreateFile(L"c:\\windows\\notepad.exe", FILE_GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
OVERLAPPED ov = {};
ov.Offset = 100;
UCHAR buf[100];
ULONG cb;
if (ReadFile(hFile, buf, sizeof(buf), &cb, &ov))
{
}
else
{
GetLastError();
}
CloseHandle(hFile);
}
你不需要调用SetFilePointer
- 在OVERLAPPED结构中更好地设置偏移量
修改强>
对于每个读/写操作,我们需要指定起始字节偏移量。我们可以通过在OVERLAPPED中设置Offset
和OffsetHigh
中的值来执行此操作。
或间接仅当同步模式下打开文件时 - I / O管理器可以使用FILE_OBJECT
中的当前文件位置 - 所以我们不能直接设置偏移量 - 它将来自FILE_OBJECT.CurrentByteOffset
。 FILE_OBJECT.CurrentByteOffset
我们可以设置SetFilePointer
每次读/写操作都会更新此偏移量 - 前进到已读/写的字节数。当然,只有当文件的所有操作都是顺序的
如果我们在OVERLAPPED
中使用直接偏移并使用 - 那么FILE_OBJECT.CurrentByteOffset
会被忽略 - 这意味着以前调用SetFilePointer
- 也会失去所有效果 - 将被使用{{1来自offset
并且在读取操作OVERLAPPED
之后将根据偏移+字节重新更新