Filesystem operations use IoError and may suspend while the runtime waits for
the host filesystem. File and Dir are stateless namespaces; OpenFile is a
live host resource.
Whole files
fn read_config(path: string): string ! IoError {
return File.read(path)?
}File.read, read_bytes, and read_lines load complete content. write,
write_bytes, append, and append_bytes create or update files.
| Method | Data shape |
|---|---|
read(path) |
UTF-8 string |
read_bytes(path) |
Owned []byte |
read_lines(path) |
Owned []string |
write(path, text) |
Create or replace text |
write_bytes(path, bytes) |
Create or replace binary data |
append, append_bytes |
Add to the end, creating when absent |
Use byte methods for protocol data or files whose encoding is not guaranteed. Whole-file methods are convenient but require memory proportional to the content size.
read_bytes_zerocopy sizes one guest buffer and fills it directly, which is
useful for large binary files. It obtains metadata first and loops over short
reads until the known size or EOF.
Metadata
File.metadata(path) returns size, file/directory/symlink flags, and readable,
writable, and executable permissions.
metadata := File.metadata(path)?
if metadata.is_file && metadata.size > MAX_UPLOAD {
error UploadError.TooLarge { size: metadata.size }
}DirEntry contains name, full path, and file/directory/symlink flags.
Metadata and entries are snapshots: another process can change the filesystem
after they are returned. Perform the actual fallible operation instead of
treating a prior exists check as a lock.
Lifecycle helpers include copy, move, delete, and delete_if_exists.
exists returns false for a missing path and also collapses permission errors;
use a fallible operation when that distinction matters.
Open handles
File.open_read and File.create return OpenFile:
file := File.open_read(path)?
mut buffer := List.with_capacity[byte](4096)
mut done := false
for !done {
count := file.read_into(buffer, 4096)?
done = count == 0
}read_into appends up to max bytes and returns the count. Zero means EOF.
It does not clear the buffer between calls. write_all consumes a borrowed byte
view, writes the complete view, and returns its length.
file := File.create(path)?
written := file.write_all(payload)?Both methods move data directly between the guest allocation and the host operation. The wrapper reserves space before a read, keeping the buffer stable while the call is suspended.
Handles close automatically through Drop, including during error
propagation. Call close() only when the resource must be released before the
end of its scope. Do not use a handle after closing it.
Directories
Dir.list returns immediate DirEntry values; Dir.walk traverses
recursively. create, create_all, delete, delete_all, copy, move, and
exists cover directory lifecycle.
Dir.delete requires an empty directory. Dir.delete_all recursively removes
contents and is intentionally destructive; keep its target derived from
validated application data rather than an unchecked user string.
Dir.create requires the parent to exist. Dir.create_all creates missing
parents. Directory copy is recursive.
Errors
IoError distinguishes missing paths, permissions, existing entries, wrong
entry kinds, non-empty directories, disk full, invalid paths, read/write
detail, timeouts, and other host failures. Match variants when callers can act
on the distinction.
match File.read(path) {
Ok(text) => parse(text)
Err(NotFound { path }) => use_default(path)
Err(PermissionDenied { path }) => report_denied(path)
Err(error) => return Err(error)
}The handle-based wrappers currently collapse negative raw host errors into the
coarse Other variant. Whole-file host operations can preserve the richer
taxonomy.
Capabilities
Host capability policy can deny filesystem operations even when source types
check. Configure only required namespaces in the project’s [host] allow-list.
Type safety does not grant ambient filesystem authority.
Filesystem paths retain host-platform semantics. Normalize or constrain paths at the application boundary when input must remain within a particular root.