Example: io.ReadSeeker / io.WriteSeeker
io.ReadSeeker and io.WriteSeeker combine sequential stream I/O with position control via Seek.
They are useful when an operation needs to jump to another location and then continue reading or writing from there.
Typical usage pattern:
If every access already carries an explicit offset, io.ReaderAt or io.WriterAt is usually a better fit because they do not alter the stream's current seek position.
Quick Example
Read from a specific position:
Seek changes the reader's current position. Subsequent reads start at this new position.
Common Use-Case: ReadSeeker
Use io.ReadSeeker when a function needs to inspect different sections of the same stream, for example, by re-reading a header:
Common Use-Case: WriteSeeker
io.WriteSeeker is useful when you need to write a placeholder first, then go back and fill in a value after its final value is known, such as a length prefix:
Common Mistakes
1. Assuming Read always fills the buffer
Read may return fewer bytes than requested without an error.
Use io.ReadFull when you need exactly the requested number of bytes:
2. Using Seek for independent random-access reads
Seek changes the stream's current position.
If you simply want bytes at a known offset, prefer ReadAt:
ReadAt uses an explicit offset and does not modify the current seek position.
3. Sharing one seeker between independent or concurrent operations
ReadSeeker and WriteSeeker carry mutable cursor state. One caller's Seek can move the cursor while another caller expects it somewhere else.
Sharing a seeker between concurrent operations requires synchronization.
For independent access, use ReaderAt / WriterAt, or give each operation its own seeker.
API Selection
Rule of Thumb
Seekmoves the current position;Atoperates at an explicit offset.