Files and console

Files and console

import std::io;
import std::fs;

io

[public] fn print(str: string)      // also number, bool, char
[public] fn println(str: string)    // also number, bool, char
[public] fn eprint(str: string)
[public] fn eprintln(str: string)
[public] fn write(fd: i32, str: string) => number?
[public] fn read_line() => string?
[public] fn read_line(fd: i32) => string?
[public] fn flush()
[public] fn stdin() => i32
[public] fn stdout() => i32
[public] fn stderr() => i32

print and println are overloaded for the four value types; the eprint pair takes only strings, so convert first. Both swallow the write result, so a failed write is silent. write returns None on failure and read_line returns None on error with the newline excluded.

fs, the simple surface

[public] fn exists(path: string) => bool
[public] fn is_directory(path: string) => bool
[public] fn make_dir(path: string) => bool
[public] fn read_file(path: string) => string?
[public] fn write_file(path: string, text: string) => bool
[public] fn append_file(path: string, text: string) => bool
[public] fn remove(path: string) => bool
[public] fn copy(src: string, dst: string) => bool
[public] fn move(src: string, dst: string) => bool
[public] fn list_dir(path: string) => Array<string>
[public] fn walk(path: string, max_depth: number) => Array<string>
[public] fn read_bytes(path: string) => Buffer?

make_dir is not recursive: create each level in turn. list_dir returns an empty array for an unreadable path rather than None, and excludes . and ... walk takes a negative depth for unlimited.

The bool returns carry no error detail. Where the reason matters, use the handle API.

Handles

File.open(mode) yields a FileHandle?. A handle holds an OS resource and must be closed:

let file: fs::File = new fs::File(path)
let opened: fs::FileHandle? = file.open(fs::OpenMode::Write)
if !opened.is_value() {
    return false
}
let handle: fs::FileHandle = opened.unwrap()
let wrote: number? = handle.write_string(text)
handle.close()
return wrote.is_value()

After close() every read and write returns None. OpenMode is Read, Write, Append, Binary, or ReadWrite; seek takes a SeekFrom of Start, Current, or End.

Buffer carries bytes with an explicit length, so it is binary safe, while the *_to_string reads stop at a NUL.

File.delete() is recursive on a directory.

BufReader and BufWriter wrap a handle for line-oriented work. A BufWriter dropped without flush() or close() loses whatever was buffered.