Winapi 从第100字节读取文件
如何使用ReadFile函数和C从第100个字节读取文件++ 我使用了这段代码,但它读取文件的前100个字节 我想读取第二个100字节Winapi 从第100字节读取文件,winapi,Winapi,如何使用ReadFile函数和C从第100个字节读取文件++ 我使用了这段代码,但它读取文件的前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
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);
你需要这样的代码
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—最好在重叠结构中直接设置偏移量
编辑
对于每个读/写操作,我们需要指定起始字节偏移量。我们可以通过设置“偏移”和“重叠的偏移高度”中的值来完成此操作
或者只有在同步模式下打开文件时才间接-I/O管理器可以使用中的当前文件位置-因此我们无法直接设置偏移量-它将从文件\u OBJECT.CurrentByteOffset获取。FILE_OBJECT.CurrentByteOffset我们还可以使用SetFilePointer设置每次读/写操作都会更新此偏移量-向前移动到读/写的字节数。当然,只有当文件的所有操作都是顺序操作时,在同步模式下使用文件时,这才是正确的
如果我们在OVERLAPPED he中使用直接偏移量,并且使用了-so FILE_OBJECT.CurrentByteOffset被忽略-这意味着之前对SetFilePointer的调用-也失去了所有效果-将从OVERLAPPED使用偏移量,并且在读取操作后,文件_OBJECT.CurrentByteOffset将根据偏移量+读取的字节进行更新执行同步I/O时设置起始偏移量的方法:
通过使用隐式存储的文件指针,该指针可以通过API调用进行操作。 或者通过结构传递一个显式偏移量。
您的代码失败,因为您正在设置隐式存储的文件指针,但随后可能会传递一个零初始化的重叠结构,该结构会忽略文件指针。有关详细信息,请参阅
以下任一解决方案都将起作用。首先,使用隐式存储的文件指针。当您希望在连续调用中读取文件块时,这非常有用:
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);
或者,可以传递重叠结构以传递偏移。这将忽略隐式存储的文件指针。它的效率稍高一些,因为它不需要对文件I/OAPI进行两次调用
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);
请注意,为了简洁起见,这些示例中省略了错误处理。在实际代码中,您必须始终检查错误。为什么要将重叠结构传递给ReadFile?将&ol更改为NULL。您在这里草拟的代码逻辑在我看来是正确的。您已经找到了正确的位置,然后从该点执行读取。当然,您没有检查任何返回值,因此您不知道这些函数中是否有任何函数出现故障。还有一个问题是,您正在将重叠结构传递给ReadFile,尽管您没有使用file_FLAG_OVERLAPPED选项打开文件句柄。@CodyGray-OVERLAPPED不仅可以用于file_FLAG_OVERLAPPED,还可以用于设置读/写操作的偏移量-因此使用OVERLAPPED是绝对正确的,另一个任务-初始化是否正确?确实可以,但是调用SetFilePointer没有意义。两种方法都可以,但不是两种都可以。StutFielPosix在概念上更简单,特别是对于文件中间的一次读取。至于如何读取块中的文件,根据原来的已删除的问题,不需要设置指针。读取前100个字节,不重叠,指针前进到100。然后读取接下来的100个字节,指针前进到200,依此类推。请不要忽略返回值。请不要发布假代码。请慢一点。请阅读以下内容:。这可能有效,但仍然无法解释调用SetFilePointer失败的原因。@RbMm好的,我说错了。但是,这仍然是一个完全的新手。他想通过零分考试,专注于基础知识。比如错误检查。事实上,他实际上希望按照前面删除的问题,以小段顺序读取文件,因此根本不需要显式设置文件指针。建议使用OVERLAPPED来指定不需要指定的文件指针对该用户没有帮助。@DavidFeffernan:是的,但在传递重叠结构时会忽略它。这句话在上下文中是正确的。对基本原理的清晰解释在哪里?询问者完全是个新手,没有多少线索。你什么都没解释。我希望看到错误检查的报道,为什么重叠结构取代了SetFilePointer,为什么顺序阅读时不需要设置文件指针。您的答案通常是这样的,技术上正确,但级别不正确,没有解释基本内容,并且经常包括血淋淋的实现细节,建议使用未记录的函数等。隐式存储的文件指针只能在同步I/O的情况下使用-当创建的文件没有文件标志重叠时