Binary file I/O

pub fn read_bytes(path: text) -> vector<u8> ?fs#read

Reads the whole file path as raw bytes. A MISSING / unreadable file reads as NULL (distinct from an EMPTY file, []); discharge with ?? [] to keep the old shape. Binary-exact (round-trips with write_bytes); use for non-UTF-8 data — for text prefer file(path).content().

pub fn file_map(path: text) -> const vector<u8> ?fs#read

Maps the whole file path READ-ONLY, without copying it: the vector's bytes ARE the file's, kept mapped for as long as the vector lives. A MISSING / unreadable file maps as NULL, like read_bytes. Every read works as on any vector<u8>; a slice is a view. The vector is const: a WRITE, to it or a slice, is refused when the program is compiled — copy first (w = v, a bind copies) to change bytes. For a file read once and whole, read_bytes gives the same bytes at the cost of the copy.

pub fn write_bytes(path: text, bytes: const vector<u8>) -> boolean fs#update

Writes bytes to file path, truncating any existing content. Returns true on success. The inverse of read_bytes; the pair round-trips a non-UTF-8 blob byte-for-byte.

pub fn mtime(path: text) -> integer fs#read

Modification time of path as Unix epoch SECONDS (integer — same i64 representation as file.size). Returns 0 on missing file / IO error / pre-epoch dates — treat 0 as "unknown". Use for date-window filters: convert the returned seconds to YYYY-MM-DD and compare lexicographically against ymd_days_ago(N).

pub fn set_file_size(self: File, size: integer) -> FileResult fs#update

Truncates or extends the file to size bytes; extending fills with zero bytes. Returns FileResult.Ok, FileResult.NotFound when the file does not exist, FileResult.IsDirectory for a directory, and FileResult.Other for a negative size or a failed OS call.

pub fn seek(self: File, pos: integer) -> boolean fs#update

Moves the read/write position to pos bytes from the start, for random access into a binary file: read an index, jump to the record it names, read that.

Equivalent to self#next = pos, the operator form.

Returns false — a no-op — when there is nothing to seek in: a directory, an absent file, or a negative pos. A seek before the first read or write is remembered and applies to it. Seeking PAST the end is allowed: the position is remembered and a following write extends the file, which is how a free-list or an update-in-place walk lands.

pub fn position(self: const File) -> integer

The current read/write position in bytes, i.e. where the next read or write will land. The read side of [seek]; self#next is the operator form.

Distinct from self#index, which is where the LAST read STARTED — after x = f#read as i32 on a fresh file, position is 4 and f#index is 0.

A file this process has not read from or written to yet has no position, and reports null rather than 0 — 0 is a legitimate position, so returning it would make "not opened" indistinguishable from "at the start". Discharge with ?? 0 when the distinction does not matter.

pub fn sync(self: File) -> boolean fs#update

Flushes buffered bytes for self to the underlying storage so that the preceding writes are durable. Use between log records or block boundaries to guarantee that earlier appends have landed on disk before later ones are issued.