File

The File: module provides text and binary file I/O. File handles are integer IDs assigned automatically by the engine when you call File:Open.


Text I/O

Call Effect
File:Open(path, mode, handle) Open file; mode is "r", "w", or "a"; handle → outVar. Read mode silently strips a UTF-8 BOM if present. Throws FileException if the file cannot be opened.
File:Close(handle) Close one file
File:CloseAll() Close all open files
File:Write(text, handle) Write string to file
File:Read(handle, outVar) Read next whitespace-delimited token → outVar
File:ReadLine(handle, outVar) Read next line → outVar
File:ReadAll(handle, outVar) Read entire remaining file content → outVar
File:EOF(handle, outVar) / File:EndOfFile(handle, outVar) true if at end of file → outVar
File:Exists(path, outVar) true if file exists → outVar
File:Delete(path, outVar) Delete file; true on success → outVar
Var:Number h;
File:Open("data.txt", "w", h);
File:Write("hello\n", h);
File:Close(h);

Var:Boolean exists;
File:Exists("data.txt", exists);
Konsol:Print(exists);       // true

// Read entire file at once
Var:String content;
Var:Number h2;
File:Open("data.txt", "r", h2);
File:ReadAll(h2, content);
File:Close(h2);
Konsol:Print(content);      // hello

// Read line by line
Var:Number h3;
Var:Boolean eof;
Var:String line;
File:Open("data.txt", "r", h3);
File:EOF(h3, eof);
while (eof == false) {
    File:ReadLine(h3, line);
    Konsol:Print(line);
    File:EOF(h3, eof);
}
File:Close(h3);

Binary I/O

Open with mode "rb", "wb", or "ab" to enable binary mode. Binary mode disables newline translation and is required for WriteBytes, ReadBytes, and ReadByte. Text methods (Write, ReadLine, etc.) still work on binary handles but are not meaningful for non-text content.

Call Effect
File:Open(path, "rb"/"wb"/"ab", handle) Open in binary mode; no newline translation
File:WriteBytes(bufName, handle) Write every element of a List:Byte or Array:Byte as raw bytes
File:ReadBytes(count, handle, listName) Read up to count bytes into a pre-declared List:Byte; clears list first; stops at EOF
File:ReadByte(handle, outVar) Read one byte (0-255) → outVar; writes -1 on EOF
// Write a small binary file
List:Byte buf;
List:Push(0x89, buf);   // PNG magic bytes (example)
List:Push(0x50, buf);
List:Push(0x4E, buf);
List:Push(0x47, buf);

Var:Number h;
File:Open("header.bin", "wb", h);
File:WriteBytes(buf, h);
File:Close(h);

// Read it back byte by byte
Var:Number h2;
File:Open("header.bin", "rb", h2);
Var:Byte b;
File:ReadByte(h2, b);
while (b != -1) {
    Konsol:Print(b);
    File:ReadByte(h2, b);
}
File:Close(h2);

// Or read all at once into a List:Byte
List:Byte data;
Var:Number h3;
File:Open("header.bin", "rb", h3);
File:ReadBytes(4, h3, data);
File:Close(h3);

Var:Number sz;
List:Size(data, sz);
Konsol:Print("read ${sz} bytes");
Note: File:WriteBytes writes raw binary content. In environments where
scripts arrive from external sources, File: should not be accessible to
untrusted scripts. See Execution control and trust model.

Errors

File operations throw FileException on failure. FileException extends Exception and exposes message, type, and code.

Situation Thrown by
File cannot be opened (bad path, permissions) File:Open
Method called with an invalid or closed handle File:Write, File:Read, File:ReadLine, File:ReadAll, File:EOF
Var:Number h;
try {
    File:Open("missing.txt", "r", h)
} catch (FileException e) {
    Konsol:Print("error: ${e.message}")
}

→ See FileObject for an OOP wrapper around this module.


Examples

// 12_file.ks - File module (write, read, readLine, EOF, exists, delete)

Konsol:Print("=== File Module ===");

Var:String path = "test_output.txt";
Var:Boolean exists;
Var:Boolean eof;
Var:String line;
Var:String token;
Var:Boolean deleted;
Var:Number fh;
Var:Number fh2;

// ── Write ─────────────────────────────────────────────────────────────────────
Konsol:Print("--- writing ${path} ---");
File:Open(path, "w", fh);
File:Write("line one\n", fh);
File:Write("line two\n", fh);
File:Write("line three\n", fh);
File:Write("42\n", fh);
File:Close(fh);
Konsol:Print("written and closed");

// ── Exists ────────────────────────────────────────────────────────────────────
File:Exists(path, exists);
Konsol:Print("Exists: ${exists}");

File:Exists("no_such_file.txt", exists);
Konsol:Print("Exists (missing): ${exists}");

// ── ReadLine until EOF ────────────────────────────────────────────────────────
Konsol:Print("--- reading lines ---");
File:Open(path, "r", fh);
Var:Number lineNum = 1;
File:EOF(fh, eof);
while (eof == false) {
    File:ReadLine(fh, line);
    Konsol:Print("line ${lineNum} : ${line}");
    lineNum++;
    File:EOF(fh, eof);
}
File:Close(fh);

// ── Append ────────────────────────────────────────────────────────────────────
Konsol:Print("--- appending ---");
File:Open(path, "a", fh);
File:Write("appended line\n", fh);
File:Close(fh);

// Re-read with Read (whitespace-delimited tokens)
Konsol:Print("--- re-read tokens ---");
File:Open(path, "r", fh);
Var:Number i = 0;
File:EOF(fh, eof);
while (eof == false && i < 6) {
    File:Read(fh, token);
    Konsol:Print("token: ${token}");
    i++;
    File:EOF(fh, eof);
}
File:Close(fh);

// ── CloseAll ──────────────────────────────────────────────────────────────────
File:Open(path, "r", fh);
File:Open(path, "r", fh2);
Konsol:Print("closing all handles");
File:CloseAll();

// ── ReadAll ───────────────────────────────────────────────────────────────────
Konsol:Print("--- ReadAll ---");
File:Open(path, "r", fh);
Var:String allContent;
File:ReadAll(fh, allContent);
File:Close(fh);
Konsol:Print(allContent);

// ── Delete ────────────────────────────────────────────────────────────────────
Konsol:Print("--- deleting ${path} ---");
File:Delete(path, deleted);
Konsol:Print("Delete returned: ${deleted}");

File:Exists(path, exists);
Konsol:Print("Exists after delete: ${exists}");