Following C# snippet executes sequential reads of pages in a binary files.
For certain delicate reasons - using ReadFile() Windows System API is a must.
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?
Thanks.
/H
CodePudding user response:
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.
This should work even if the file was not opened for overlapped I/O.
CodePudding user response:
You are setting the lpOverlapped parameter of ReadFile() to a reference to an _overlapped variable. So you need to use the _overlapped.Offset and _overlapped.OffsetHigh fields to specify the desired file offset to read from.
Per the ReadFile() documentation:
[in, out, optional] lpOverlappedA pointer to an
OVERLAPPEDstructure is required if thehFileparameter was opened withFILE_FLAG_OVERLAPPED, otherwise it can be NULL.If
hFileis opened withFILE_FLAG_OVERLAPPED, thelpOverlappedparameter must point to a valid and uniqueOVERLAPPEDstructure, otherwise the function can incorrectly report that the read operation is complete.For an
hFilethat supports byte offsets, if you use this parameter you must specify a byte offset at which to start reading from the file or device. This offset is specified by setting theOffsetandOffsetHighmembers of theOVERLAPPEDstructure. For anhFilethat does not support byte offsets,OffsetandOffsetHighare ignored.For more information about different combinations of
lpOverlappedandFILE_FLAG_OVERLAPPED, see the Remarks section and the Synchronization and File Position section.
And the "Synchronization and File Position" section says:
If
hFileis opened withFILE_FLAG_OVERLAPPED, it is an asynchronous file handle; otherwise it is synchronous. The rules for using theOVERLAPPEDstructure are slightly different for each, as previously noted....
Considerations for working with asynchronous file handles:
- ...
- The lpOverlapped parameter must not be NULL and should be used with the following facts in mind:
- 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.
- ...
- Because the read operation starts at the offset that is specified in the
OVERLAPPEDstructure, andReadFilemay 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).- ...
Considerations for working with synchronous file handles:
- ...
- If
lpOverlappedis not NULL, the read operation starts at the offset that is specified in theOVERLAPPEDstructure andReadFiledoes not return until the read operation is complete. The system updates theOVERLAPPEDoffset beforeReadFilereturns.- ...
Had you been setting the lpOverlapped parameter to null instead, then you would have to use SetFilePointer() or SetFilePointerEx() to specify the desired offset:
Considerations for working with synchronous file handles:
- If
lpOverlappedis NULL, the read operation starts at the current file position andReadFiledoes not return until the operation is complete, and the system updates the file pointer beforeReadFilereturns.- ...
CodePudding user response:
I believe you should be able to do this with SetFilePointer or SetFilePointerEx. 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
