Quirrel4.41.0

io.file.seek

Method of file, from module "io"
instance.seek(offset: int, [origin: int]): int

Seeks to the given offset; origin is 'b' (begin), 'c' (current) or 'e' (end)

examples/io/file/seek-basic.nut
from "io" import file
from "system" import getenv, remove

let path = $"{getenv("TEMP") ?? getenv("TMP") ?? "/tmp"}/qrl_io_file_seek_basic.tmp"
let f = file(path, "w+")
f.writestring("ammo42")

f.seek(4)                // absolute offset from the start
println("f.readblob(2).as_string() =", f.readblob(2).as_string())

f.close()
remove(path)
Output:
f.readblob(2).as_string() = 42

Parameters

offsetinthow far to move
originint'b' (begin), 'c' (current) or 'e' (end); defaults to 'b' optional

Return value

See iostream.stream.seek for the generic contract.

Errors

Throws invalid origin when origin is not 'b', 'c' or 'e'. Throws the stream is invalid once the file has been closed.

Notes

Unlike a blob, seeking past the real end of a file is not an error: the OS allows it, seek returns success, and tell reports the new position, even though nothing was written there. A read at that position still fails, and a write there grows the file, leaving a hole that reads back as zero bytes.

A seek that resolves before byte 0 fails and returns -1; whether the cursor itself moves on that failure can depend on the platform's C library and on whether the last operation was a read, so treat -1 as the only guarantee and re-seek explicitly afterward if the position matters.

Example

examples/io/file/seek.nut
from "io" import file
from "system" import getenv, remove

let path = $"{getenv("TEMP") ?? getenv("TMP") ?? "/tmp"}/qrl_io_file_seek.tmp"
let f = file(path, "w+")
f.writestring("abcdef")

println("f.seek(-2, 'e') =", f.seek(-2, 'e'))   // two bytes back from the real end
println("f.readn('b') =", f.readn('b'))      // 'e' = 101

println("f.seek(100, 'b') =", f.seek(100, 'b'))  // past the real end is not an error for a file
println("f.tell() =", f.tell())

try { f.seek(0, 'z'); }
catch (e) { println("f.seek(0, 'z') throws:", e); } // only the origin character is validated

f.close()
remove(path)
Output:
f.seek(-2, 'e') = 0
f.readn('b') = 101
f.seek(100, 'b') = 0
f.tell() = 100
f.seek(0, 'z') throws: invalid origin

See also

seekSeeks to the given offset; origin is 'b' (begin), 'c' (current) or 'e' (end)
tellReturns the current stream position
lenReturns the stream length
fileclass index