Every file port maintains a file pointer, which is the position within the file from which data is read and to which it is written. Use file-position to get and set the file pointer. file-position takes one or two arguments. When given one argument, that argument is a port and it returns the current position of the file pointer. When given two arguments, the first is a port and the second is a positive integer which specifies the new position for the file pointer in bytes. For example:
;; Write some test data to a file
>(with-output-to-file"test.txt"
(lambda ()
(display"Hello there.\nThis is a test.\n")))
;; Open the file we have just written
> (defineport (open-input-file"test.txt"))
;; Get the current file position
> (file-positionport)
0;; Read the current line
> (read-lineport)
"Hello there.";; Show the file position has advanced
> (file-positionport)
13;; Skip ahead 4 bytes
> (file-positionport (+4 (file-positionport)))
;; Read the next line to show we have skipped ahead
> (read-lineport)
" is a test.";; Clean up
(close-input-portport)
So if you know records are 5 bytes in length, and you want the 5th record, you would set the file pointer to be 5*5 = 25 and read from there.
Only string and file ports are guaranteed to support file-position. Changing the file pointer with file-position always clears the buffer for an input port, and flushes the buffer for an output port. Although ports opened with open-input-output-file share the same file pointer setting the position via one port does not flush the other's buffer.
Setting the file pointer past the end of a file causes the file to be enlarged and filled with #\nul up to the required size.
For some applications peeking, which reads without advancing the file pointer, may be preferrable. The main peeking functions are peek-string and peek-bytes.