Home > OS >  How to read a file at a specific offset position using ReadFile() Windows API (C#)?
How to read a file at a specific offset position using ReadFile() Windows API (C#)?

Time:07-08

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 the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be 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.

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 the Offset and OffsetHigh members of the OVERLAPPED structure. For an hFile that does not support byte offsets, Offset and OffsetHigh are ignored.

For more information about different combinations of lpOverlapped and FILE_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 with FILE_FLAG_OVERLAPPED, it is an asynchronous file handle; otherwise it is synchronous. The rules for using the OVERLAPPED 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, 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).
    • ...

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. The system updates the OVERLAPPED offset before ReadFile 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 and ReadFile does not return until the operation is complete, and the system updates the file pointer before ReadFile 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

  • Related