It all comes down to visualization.
I think of a file as a zero based array. I.e. byte at index 0
etc.
For file operations I tend to think of it like the pointer is between indexes. It is kind of an in limbo indicator. What to expect from the future. This also relate to SEEK_END
as one can think of it of what one want to do in the future.
SEEK_END -3
- Now I can read last 3 bytes.
SEEK_END 0
- No more bytes. Now I can append bytes.
- ...
If offset is for example 4
then I know next byte is at index 4
and last read byte was at index 3
.
0 1 2 3 4 5 6 7 Offset
+---+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Index
+---+---+---+---+---+---+---+
| | |
| | +--- Next Index
| +----- Offset 4
+------- Last Index
Some might find it awkward, but works for me.
As for SEEK_END
it is in the name. Seek relative to END. END is all read, indicating there is nothing left. The SEEK_END
and SEEK_SET
also have a direct relation as:
SEEK_SET - SIZE = SEEK_END
SEEK_END + SIZE = SEEK_SET
SEEK_SET - SEEK_END = SIZE
SEEK_SET + abs(SEEK_END) = SIZE
In the final diagram we have OFFSET
and ORIGIN
as arguments for seek()
.
(Size: 7 bytes) ,-- END of FILE
/
0 1 2 3 4 5 6 | O O | BYTES |
+---+---+---+---+---+---+---+ F R | L | R |
| A | B | C | D | E | F | G | F I | E | E |
+---+---+---+---+---+---+---+ S G | F | A |
| | | | E I | T | D |
| | | | T N . . RELATION
| | | | . . . .
| | | +-- 7, SEEK_SET | 0 | 7 | 7 - 7 = 0
| | | +-+ 0, SEEK_END | 0 | 7 | 0 + 7 = 7
| | | | 7 - -0 = 7
| | | |
| | +-----| 6, SEEK_SET | 1 | 6 | 6 - 7 = -1
| | +-----+ -1, SEEK_END | 1 | 6 | -1 + 7 = 6
| | | 6 - -1 = 7
| | |
| +-------------| 4, SEEK_SET | 3 | 4 | 4 - 7 = -3
| +-------------+ -3, SEEK_END | 3 | 4 | -3 + 7 = 4
| | 4 - -3 = 7
| |
+-----------------------------| 0, SEEK_SET | 7 | 0 | 0 - 7 = -7
+-----------------------------+ -7, SEEK_END | 7 | 0 | -7 + 7 = 0
| | 0 - -7 = 7
fseek(fh, offs, origin) |
/
ftell() -´
SEEK_END
? (just asking, I don't know) – Flail