file_io
Ergonomic wrappers around the low-level fs package. Provides Python-style convenience for reading entire files, writing strings, copying, renaming, and working with paths. Depends on fs.jda.
Usage
import fs
import file_io
fn main() {
// Read an entire file
let buf = fs_slurp("/tmp/data.txt")
let size = fs_file_size("/tmp/data.txt")
// Count lines
let lines = buf_count_lines(buf, size)
print(lines)
// Write a string to a file
fs_write_str("/tmp/out.txt", "hello world\n", 12)
// Copy a file
fs_copy("/tmp/out.txt", "/tmp/backup.txt")
// Path manipulation
let out: &i8 = alloc_pages(1)
let len = path_join("/home/user", 10, "file.txt", 8, out)
// out now contains: /home/user/file.txt
}Function Reference
| Function | Signature | Description |
|---|---|---|
fs_slurp | (path: &i8) -> i64 | Read entire file into a buffer |
fs_write_str | (path: &i8, data: &i8, len: i64) -> i64 | Write string to file |
fs_append_str | (path: &i8, data: &i8, len: i64) -> i64 | Append string to file |
fs_copy | (src: &i8, dst: &i8) -> i64 | Copy a file |
fs_rename | (src: &i8, dst: &i8) -> i64 | Rename/move a file |
fs_tmpname | (out: &i8, suffix: i64) -> i64 | Generate a temp file path |
buf_count_lines | (buf: &i8, len: i64) -> i64 | Count lines in a buffer |
buf_line_start | (buf: &i8, len: i64, line_idx: i64) -> i64 | Get offset of line N |
buf_line_len | (buf: &i8, total_len: i64, start: i64) -> i64 | Get length of line at offset |
path_join | (dir: &i8, dir_len: i64, name: &i8, name_len: i64, out: &i8) -> i64 | Join directory and filename |
path_basename | (path: &i8, len: i64) -> i64 | Find basename offset in path |
path_ext | (path: &i8, len: i64) -> i64 | Find extension dot offset |
cstr_length | (s: &i8) -> i64 | Length of null-terminated string |
buf_eq | (a: &i8, b: &i8, n: i64) -> i64 | Compare n bytes for equality |
Detailed API
fs_slurp
fn fs_slurp(path: &i8) -> i64Read an entire file into an auto-allocated buffer. Uses fs_file_size to determine the size, allocates pages, and reads the file contents. Use fs_file_size separately to get the byte count.
let buf: &i8 = fs_slurp("/etc/hostname")
let size = fs_file_size("/etc/hostname")
// buf[0..size] now contains the file contentsReturns: Pointer to the buffer (cast to i64), or 0 on error.
fs_write_str
fn fs_write_str(path: &i8, data: &i8, len: i64) -> i64Write len bytes from data to a file, creating or truncating it. Like Python’s open(f, 'w').write(data).
let msg = "Hello, World!\n"
let n = fs_write_str("/tmp/greeting.txt", msg, 14)
print(n) // 14 (bytes written)Returns: Number of bytes written, or -1 on error.
fs_append_str
fn fs_append_str(path: &i8, data: &i8, len: i64) -> i64Append len bytes to an existing file. Like Python’s open(f, 'a').write(data).
fs_append_str("/tmp/log.txt", "entry 1\n", 8)
fs_append_str("/tmp/log.txt", "entry 2\n", 8)Returns: Number of bytes written, or -1 on error.
fs_copy
fn fs_copy(src: &i8, dst: &i8) -> i64Copy a file from src to dst. Reads the entire source file into memory and writes it to the destination.
let r = fs_copy("/tmp/original.txt", "/tmp/backup.txt")
if r < 0 { print("copy failed") }Returns: Bytes written on success, -1 on error.
fs_rename
fn fs_rename(src: &i8, dst: &i8) -> i64Rename or move a file. Uses Linux rename syscall (82).
fs_rename("/tmp/old.txt", "/tmp/new.txt")Returns: 0 on success, -1 on error.
fs_tmpname
fn fs_tmpname(out: &i8, suffix: i64) -> i64Generate a temporary file path of the form /tmp/jda_NNNN where NNNN is the decimal representation of suffix. The path is null-terminated.
let out: &i8 = alloc_pages(1)
let len = fs_tmpname(out, 12345)
// out now contains: /tmp/jda_12345\0Returns: Length of the path (not including null terminator).
buf_count_lines
fn buf_count_lines(buf: &i8, len: i64) -> i64Count the number of lines in a buffer. Counts newline characters, adding 1 if the buffer does not end with a newline.
let text = "line1\nline2\nline3"
let n = buf_count_lines(text, 17)
print(n) // 3buf_line_start
fn buf_line_start(buf: &i8, len: i64, line_idx: i64) -> i64Get the byte offset where line number line_idx (0-indexed) begins.
let text = "aaa\nbbb\nccc"
let start = buf_line_start(text, 11, 1)
print(start) // 4 (start of "bbb")buf_line_len
fn buf_line_len(buf: &i8, total_len: i64, start: i64) -> i64Get the length of a line starting at offset start, excluding the newline character.
let text = "aaa\nbbb\nccc"
let start = buf_line_start(text, 11, 1)
let llen = buf_line_len(text, 11, start)
print(llen) // 3 (length of "bbb")path_join
fn path_join(dir: &i8, dir_len: i64, name: &i8, name_len: i64, out: &i8) -> i64Join a directory and filename with /. If the directory already ends with /, no extra separator is added. The result is null-terminated.
let out: &i8 = alloc_pages(1)
let len = path_join("/home/user", 10, "data.txt", 8, out)
// out contains: /home/user/data.txt\0
print(len) // 19Returns: Length of the resulting path.
path_basename
fn path_basename(path: &i8, len: i64) -> i64Find the offset where the filename begins in a path (after the last /).
let offset = path_basename("/foo/bar/baz.txt", 16)
print(offset) // 9 (points to 'b' in "baz.txt")Returns: Byte offset of the basename.
path_ext
fn path_ext(path: &i8, len: i64) -> i64Find the position of the last . in the filename portion of a path. Returns len if there is no extension.
let dot = path_ext("/foo/bar.txt", 12)
print(dot) // 8 (position of '.')Returns: Offset of the extension dot, or len if no extension.
cstr_length
fn cstr_length(s: &i8) -> i64Get the length of a null-terminated C string by scanning for the \0 byte.
let len = cstr_length("hello")
print(len) // 5buf_eq
fn buf_eq(a: &i8, b: &i8, n: i64) -> i64Compare n bytes of two buffers for equality.
print(buf_eq("abc", "abc", 3)) // 1
print(buf_eq("abc", "abd", 3)) // 0Returns: 1 if all bytes match, 0 otherwise.