简体   繁体   English

如何使用 ReadFile() Windows API (C#) 在特定偏移位置读取文件?

[英]How to read a file at a specific offset position using ReadFile() Windows API (C#)?

Following C# snippet executes sequential reads of pages in a binary files.以下 C# 代码片段执行二进制文件中页面的顺序读取。

For certain delicate reasons - using ReadFile() Windows System API is a must.出于某些微妙的原因 -必须使用 ReadFile() Windows 系统 API。

for (iReadCounter = 0; iReadCounter < iReadCountLimit; iReadCounter++)
{
    readsize = DefineConstants.READ_BUF_SIZE;
    bool bResult = ReadFile(fhnd, readbuffer, (uint)readsize, out readresult, ref _overlapped);
    .
    .
}

Is there a way by which ReadFile() can be directed to read at a specific file offset/position of choice?有没有办法可以引导ReadFile()在特定的文件偏移/选择位置读取?

Thanks.谢谢。

/H /H

You are setting the lpOverlapped parameter of ReadFile() to a reference to an _overlapped variable.您正在将ReadFile()lpOverlapped参数设置为对_overlapped变量的引用。 So you need to use the _overlapped.Offset and _overlapped.OffsetHigh fields to specify the desired file offset to read from.因此,您需要使用_overlapped.Offset_overlapped.OffsetHigh字段来指定要读取的所需文件偏移量。

Per the ReadFile() documentation:根据ReadFile()文档:

[in, out, optional] lpOverlapped

A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED , otherwise it can be NULL.如果使用FILE_FLAG_OVERLAPPED打开hFile参数,则需要指向OVERLAPPED结构的指针,否则它可以为 NULL。

If hFile is opened with FILE_FLAG_OVERLAPPED , the lpOverlapped parameter must point to a valid and unique OVERLAPPED structure, otherwise the function can incorrectly report that the read operation is complete.如果使用FILE_FLAG_OVERLAPPED打开hFile ,则lpOverlapped参数必须指向一个有效且唯一的OVERLAPPED结构,否则该函数可能会错误地报告读取操作已完成。

For an hFile that supports byte offsets, if you use this parameter you must specify a byte offset at which to start reading from the file or device.对于支持字节偏移的hFile ,如果使用此参数,则必须指定开始从文件或设备读取的字节偏移。 This offset is specified by setting the Offset and OffsetHigh members of the OVERLAPPED structure.通过设置OVERLAPPED结构的OffsetOffsetHigh成员来指定此偏移量。 For an hFile that does not support byte offsets, Offset and OffsetHigh are ignored.对于不支持字节偏移的hFileOffsetOffsetHigh将被忽略。

For more information about different combinations of lpOverlapped and FILE_FLAG_OVERLAPPED , see the Remarks section and the Synchronization and File Position section.有关lpOverlappedFILE_FLAG_OVERLAPPED不同组合的更多信息,请参阅备注部分和同步和文件位置部分。

And the "Synchronization and File Position" section says: “同步和文件位置”部分说:

If hFile is opened with FILE_FLAG_OVERLAPPED , it is an asynchronous file handle;如果hFile是用FILE_FLAG_OVERLAPPED打开的,它是一个异步文件句柄; otherwise it is synchronous.否则它是同步的。 The rules for using the OVERLAPPED structure are slightly different for each, as previously noted.如前所述,每个使用OVERLAPPED结构的规则略有不同。

... ...

Considerations for working with asynchronous file handles:使用异步文件句柄的注意事项:

  • ... ...
  • The lpOverlapped parameter must not be NULL and should be used with the following facts in mind: lpOverlapped 参数不得为 NULL,使用时应牢记以下事实:
    • Although the event specified in the OVERLAPPED structure is set and reset automatically by the system, the offset that is specified in the OVERLAPPED structure is not automatically updated .尽管 OVERLAPPED 结构中指定的事件由系统自动设置和重置,但 OVERLAPPED 结构中指定的偏移量不会自动更新
    • ... ...
    • Because the read operation starts at the offset that is specified in the OVERLAPPED structure , and ReadFile may return before the system-level read operation is complete (read pending), neither the offset nor any other part of the structure should be modified, freed, or reused by the application until the event is signaled (that is, the read completes).因为读取操作从OVERLAPPED结构中指定的偏移量开始,并且ReadFile可能在系统级读取操作完成(读取挂起)之前返回,所以无论是偏移量还是结构的任何其他部分都不应被修改、释放、或由应用程序重用,直到发出事件信号(即读取完成)。
    • ... ...

Considerations for working with synchronous file handles:使用同步文件句柄的注意事项:

  • ... ...
  • If lpOverlapped is not NULL, the read operation starts at the offset that is specified in the OVERLAPPED structure and ReadFile does not return until the read operation is complete.如果lpOverlapped不为 NULL,则读取操作从OVERLAPPED结构中指定的偏移量开始,并且ReadFile在读取操作完成之前不会返回。 The system updates the OVERLAPPED offset before ReadFile returns.系统会在ReadFile返回之前更新OVERLAPPED偏移量。
  • ... ...

Had you been setting the lpOverlapped parameter to null instead, then you would have to use SetFilePointer() or SetFilePointerEx() to specify the desired offset:如果您将lpOverlapped参数设置为null ,那么您将不得不使用SetFilePointer()SetFilePointerEx()来指定所需的偏移量:

Considerations for working with synchronous file handles:使用同步文件句柄的注意事项:

  • If lpOverlapped is NULL, the read operation starts at the current file position and ReadFile does not return until the operation is complete, and the system updates the file pointer before ReadFile returns.如果lpOverlapped为 NULL,则读取操作从当前文件位置开始ReadFile直到操作完成才返回,系统在ReadFile返回之前更新文件指针。
  • ... ...

If the file actually supports reading at a specific position (not a given), you should be able to use the Offset and OffsetHigh members of the OVERLAPPED parameter to specify the read position.如果文件实际上支持在特定位置(不是给定位置)读取,您应该能够使用 OVERLAPPED 参数的 Offset 和 OffsetHigh 成员来指定读取位置。

This should work even if the file was not opened for overlapped I/O.即使没有为重叠 I/O 打开文件,这也应该有效。

I believe you should be able to do this with SetFilePointer or SetFilePointerEx .我相信您应该能够使用SetFilePointerSetFilePointerEx做到这一点。 It allows you to set where the file handle is pointing at.它允许您设置文件句柄指向的位置。

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfilepointer https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfilepointer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM