File API
File reading and writing — whole-file helpers, streaming handles with typed binary I/O, and transparent compression and encryption.
Overview
The global identifier File is a namespace of static helpers and opener constructors. Opening a file returns a file handle whose instance methods are invoked as f.method(...). Static helpers cover whole-file reads and writes, metadata queries, and filesystem operations; handles provide streaming block, text, and typed binary I/O with per-handle or per-call endianness control.
Conventions
Paths. Strings are interpreted as filesystem paths, absolute or relative to the current working directory. No virtual-filesystem prefixes are applied.
Modes. The open* functions take a mode string:
| Mode | Meaning |
|---|---|
"r" | Read-only; the file must exist. |
"w" | Write; truncates or creates. |
"rw" | Read + write; the file must exist, position starts at 0. |
"wr" | Write + read; truncates or creates. |
Numbers. Sizes, offsets, positions, byte values, and timestamps are Zym numbers. Integer methods truncate toward zero.
Buffers. Byte I/O uses Buffer instances.
Endianness. Typed multi-byte reads and writes accept an optional trailing "le" (default) or "be" string — see Endianness.
Open failures. open, openCompressed, openEncryptedPass, and openEncrypted return null on failure — check with if f == null. Use lastError(), or a handle's getError(), for a numeric status. The whole-file helpers (File.readText / File.readBytes) instead raise a runtime error.
Errors. Invalid argument types, bad modes, negative sizes, or operations on a closed handle produce a Zym runtime error of the form File.method(args) ....
Opening Files
Four opener constructors return file handles, or null on failure. Compression and encryption support depends on the build.
Opens a file and returns a handle, or null on failure.
path(string) — filesystem path, absolute or relative to the current working directorymode(string) —"r","w","rw", or"wr"(see Conventions)
var f = File.open("data.bin", "r") if (f == null) { print("open failed") } else { // ... use the handle ... f.close() }
Opens a handle over a compressed stream, or returns null on failure. Availability of each algorithm depends on the build; an unsupported algorithm causes the open call to fail (null).
algo(string) —"fastlz","deflate","zstd","gzip", or"brotli"
"brotli" cannot be used with openCompressed for round-trip I/O. Opening for write ("w" / "wr") succeeds, but the close step fails with "Only brotli decompression is supported." and produces an empty file. Opening for read ("r" / "rw") only accepts streams in the engine's own framed compressed-file container — which the engine itself cannot produce — so there is currently no supported way to read a brotli stream through this API. Use one of the other algorithms for round-trip compression.
Opens a handle over a password-encrypted stream, or returns null on failure. The encryption key is derived from password. Files written with openEncryptedPass can only be read back by openEncryptedPass with the same password.
Opens a handle over an AES-256-CBC encrypted stream, or returns null on failure. A fresh 16-byte IV is generated on write and stored in the file header, so reads do not need it. Files written with openEncrypted can only be read back by openEncrypted with the same key.
key(Buffer) — must be exactly 32 bytes; any other length raises a runtime error
Crypto.create().generateRandomBytes(32) — and store it separately; losing the key makes the file unrecoverable. openEncrypted and openEncryptedPass share an on-disk container format but differ in how the key is derived, so their files are not interchangeable. For in-memory encryption with a custom IV, use the AES native directly.
Whole-File Helpers
Convenience wrappers that open, transfer, and close in one call. The readers raise a runtime error on failure rather than returning null.
Reads the entire file into a new Buffer. Raises a runtime error on failure.
Reads the entire file as UTF-8 text. Raises a runtime error on failure.
Truncates or creates the file and writes the buffer. Returns a boolean.
Truncates or creates the file and writes the string. Returns a boolean.
Appends to an existing file, or creates one. Opens the file in read/write mode (falling back to write mode for new files), seeks to the end before writing, and closes the handle for you. Returns a boolean.
data(string or Buffer) — content to append
File.writeText("greeting.txt", "hello\n") File.append("greeting.txt", "goodbye\n") print("%s", File.readText("greeting.txt"))
Metadata
Returns true if a regular file exists at path.
Returns the size in bytes, or 0 if the file is missing. Pair with exists to distinguish missing files from empty ones.
Returns the Unix timestamp (seconds) of the last modification. Returns 0 rather than raising when the path does not exist.
Returns the Unix timestamp (seconds) of the last access. Returns 0 rather than raising when the path does not exist.
Returns the MD5 hash of the file contents as lower-case hex. Streams the whole file, so it can be slow on large inputs.
Returns the SHA-256 hash of the file contents as lower-case hex. Streams the whole file, so it can be slow on large inputs.
Filesystem Operations
Copies a file. Returns true on success.
Deletes a file. Returns true on success.
Renames or moves a file. Returns true on success.
Handle State & Positioning
Returns true while the handle holds an open file.
Flushes and closes the handle. Safe to call more than once.
close(), calling any method other than isOpen(), close(), path(), pathAbsolute(), or getError() raises a runtime error.
Returns the path as originally passed to the opener.
Returns the absolute path.
Returns the current file size in bytes.
Returns the current cursor offset.
Moves the cursor to the absolute byte offset pos.
pos(number) — absolute byte offset (0 or greater)
Moves the cursor to length() + off. Use 0 for end-of-file.
off(number) — offset relative to the end of the file
Returns true after a read has passed the last byte.
Flushes pending writes to disk.
Truncates or extends the file to n bytes. Returns a status code (0 on success). Newly exposed bytes on growth are not zero-filled on all platforms; write explicit zeros if you need a known state.
Returns the last error code observed on the handle (0 = ok).
Sets the handle-wide endianness default for typed I/O. See Endianness.
b(boolean) —truefor big-endian,falsefor little-endian (the default)
Returns the current handle-wide endianness setting.
var f = File.open("data.bin", "rw") f.seekEnd(0) // jump to end-of-file print("%n bytes", f.position()) f.seek(0) // back to the start f.close()
Block I/O
Reads up to n bytes from the cursor into a new Buffer. The returned buffer may be shorter than n near end-of-file — check buf.size() on the result rather than assuming the full count.
n(number) — maximum number of bytes to read
Writes the entire contents of buf at the cursor. Returns a boolean.
buf(Buffer) — bytes to write
Text I/O
Reads the remaining bytes as UTF-8 text.
Reads one line, up to and excluding the newline.
Parses one CSV row into a list of strings.
delim(string, optional) — field delimiter (default:",")
Writes the raw UTF-8 bytes of s with no trailing newline. Returns a boolean.
Writes s followed by a newline. Returns a boolean.
Writes list as a CSV row. All elements must be strings. Returns a boolean.
list(list) — row fields; all elements must be stringsdelim(string, optional) — field delimiter (default:",")
var out = File.open("table.csv", "w") out.writeCSVLine(["name", "score"]) out.writeCSVLine(["alice", "98"]) out.close() var src = File.open("table.csv", "r") var header = src.readCSVLine() // ["name", "score"] var row = src.readCSVLine() // ["alice", "98"] src.close()
Integer Decode & Encode
Typed integer I/O at the cursor. Signed variants sign-extend; unsigned variants zero-extend. All multi-byte methods accept an optional trailing endian override e — "le" or "be". When omitted, the handle's current endian setting (see setBigEndian) is used. The 1-byte methods accept e for API symmetry but ignore it.
U64 and I64 values beyond that range silently round on decode and lose low-order bits on encode. If you need exact 64-bit values, split them into two 32-bit halves with writeU32 / readU32.
Integer Reads
Reads an unsigned 8-bit integer (0–255).
Reads a signed 8-bit integer (−128 to 127).
Reads an unsigned 16-bit integer (0–65,535).
Reads a signed 16-bit integer (−32,768 to 32,767).
Reads an unsigned 32-bit integer (0–4,294,967,295).
Reads a signed 32-bit integer (−2,147,483,648 to 2,147,483,647).
Reads an unsigned 64-bit integer. Values outside the exact-integer range silently round on decode — see the precision note above.
Reads a signed 64-bit integer. Values outside the exact-integer range silently round on decode — see the precision note above.
Integer Writes
Writes an unsigned 8-bit integer (0–255).
Writes a signed 8-bit integer (−128 to 127).
Writes an unsigned 16-bit integer.
Writes a signed 16-bit integer.
Writes an unsigned 32-bit integer.
Writes a signed 32-bit integer.
Writes an unsigned 64-bit integer. Values outside the exact-integer range lose low-order bits on encode — see the precision note above.
Writes a signed 64-bit integer. Values outside the exact-integer range lose low-order bits on encode — see the precision note above.
var f = File.open("data.bin", "w") f.writeU32(0xCAFEBABE, "be") // per-call big-endian f.writeU16(1) // handle default (LE) f.writeI8(-5) f.close()
Float Decode & Encode
IEEE 754 floating-point I/O at the cursor. All float methods accept the same optional trailing endian override as the integer methods.
Reads a 2-byte IEEE 754 half-precision float.
Reads a 4-byte IEEE 754 single-precision float.
Reads an 8-byte IEEE 754 double-precision float.
Writes a 2-byte IEEE 754 half-precision float. Narrows a Zym number (a double) to half precision; round-tripping is lossy for most values.
Writes a 4-byte IEEE 754 single-precision float. Narrows a Zym number (a double) to single precision; round-tripping is lossy for most values.
Writes an 8-byte IEEE 754 double-precision float.
Endianness
Typed multi-byte reads and writes on a file handle consult, in order:
- An explicit trailing
"le"or"be"argument at the call site, if provided. The handle's setting is not modified. - Otherwise, the handle-wide setting from
setBigEndian(true|false)(default: little-endian).
Any string other than "le" / "be", or a non-string value in the endian slot, raises a runtime error.
setBigEndian(true) with per-call "le" overrides is supported, but the per-call override does not change the handle's setting. Be explicit when interleaving.
var f = File.open("out.bin", "w") f.writeU32(0x11223344, "be") // per-call override f.setBigEndian(true) f.writeU32(0x55667788) // uses handle default (BE) f.close()
Examples
End-to-End File I/O
// Whole-file helpers File.writeText("hello.txt", "hello\n") print("%s", File.readText("hello.txt")) print("size=%n exists=%b", File.size("hello.txt"), File.exists("hello.txt")) print("sha=%s", File.sha256("hello.txt")) // Streaming read var f = File.open("hello.txt", "r") if (f == null) { print("open failed") } else { while (!f.eof()) { var line = f.readLine() if (line != "") { print("> %s", line) } } f.close() } // Binary write + seek var g = File.open("out.bin", "w") g.writeU32(0xCAFEBABE, "be") g.writeFloat(3.14) g.close() File.remove("hello.txt") File.remove("out.bin")