Search code examples
c#filestream

Does FileStream.Seek() with SeekOrigin.Begin optimize for when no seeking is necessary?


I have a class that reads image data a row at a time from large files using FileStream. Internally, the files are broken into chunks, each of which looks like this:

=================
| Header        |
=================
| Data I Want   |
=================
| Data I Ignore |
=================

To read a row of data, I calculate which chunk has the row I want, Seek() to the appropriate offset, and read a fixed number of bytes. When reading multiple rows from within a single chunk, I could actually skip all Seek() calls but the first, because the pointer is already where I want it after a Read(). But I need to Seek() when jumping to a new chunk. For simplicity, I always calculate the next row's absolute offset in the file and Seek() to it using SeekOrigin.Begin. Is FileStream.Seek() (or the underlying SetFilePointer() native function) optimized to recognize that a given seek is a no-op? If not, I should probably optimize my own code, as it's not exactly lightning-fast.


Solution

  • The answer seems to be Yes.

    The only concern here is the read buffer. We may assume the underlying SetFilePointer() call will be a non-op for a seek-to-current.

    When you consult the source for Seek, you can see that an attempt is made to preserve as much as possible from the read buffer.