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] lpOverlapped
A pointer to an
OVERLAPPED
structure is required if thehFile
parameter was opened withFILE_FLAG_OVERLAPPED
, otherwise it can be NULL.If
hFile
is opened withFILE_FLAG_OVERLAPPED
, thelpOverlapped
parameter must point to a valid and uniqueOVERLAPPED
structure, otherwise the function can incorrectly report that the read operation is complete.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. This offset is specified by setting theOffset
andOffsetHigh
members of theOVERLAPPED
structure. For anhFile
that does not support byte offsets,Offset
andOffsetHigh
are ignored.For more information about different combinations of
lpOverlapped
andFILE_FLAG_OVERLAPPED
, see the Remarks section and the Synchronization and File Position section.
And the "Synchronization and File Position" section says:
If
hFile
is opened withFILE_FLAG_OVERLAPPED
, it is an asynchronous file handle; otherwise it is synchronous. The rules for using theOVERLAPPED
structure 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
OVERLAPPED
structure, andReadFile
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).- ...
Considerations for working with synchronous file handles:
- ...
- If
lpOverlapped
is not NULL, the read operation starts at the offset that is specified in theOVERLAPPED
structure andReadFile
does not return until the read operation is complete. The system updates theOVERLAPPED
offset beforeReadFile
returns.- ...
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
lpOverlapped
is NULL, the read operation starts at the current file position andReadFile
does not return until the operation is complete, and the system updates the file pointer beforeReadFile
returns.- ...
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