Skip to content

std.fs

sync files and folders; paths over 1023 bytes fail with path_too_long

pub FsError :: errors {
not_found,
create_failed,
read_failed,
write_failed,
seek_failed,
delete_failed,
path_too_long,
rename_failed,
}
  • not_found: missing path (or access denied)
  • create_failed: create/append failed
  • read_failed: a read returned an error
  • write_failed: a write returned an error
  • seek_failed: a seek returned an error
  • delete_failed: delete failed (or folder not empty)
  • path_too_long: path + NUL over 1024 bytes
  • rename_failed: rename could not move the file
pub File :: struct {
handle: i64,
}

open OS file; a Reader and a Writer

pub is_open :: fn(self: *File) -> bool
pub close :: fn(self: *File)

close the handle; idempotent

pub open :: fn(path: []const u8) -> File ! FsError

open for reading; not_found if it can’t be

pub create :: fn(path: []const u8) -> File ! FsError

create for writing; truncates an existing file

pub append :: fn(path: []const u8) -> File ! FsError

open for appending; creates it if missing

pub exists :: fn(path: []const u8) -> bool

file or dir exists; never fails

pub is_dir :: fn(path: []const u8) -> bool
pub delete :: fn(path: []const u8) -> void ! FsError

remove a file; delete_failed if it can’t

pub make_dir :: fn(path: []const u8) -> void ! FsError

make folder path (ok if it exists); create_failed if no parent or a file is there

pub make_dirs :: fn(path: []const u8) -> void ! FsError

make path and any missing parents (/ or \ separators)

pub remove_dir :: fn(path: []const u8) -> void ! FsError

remove empty folder path; delete_failed otherwise

pub read_all :: fn(path: []const u8, a: *Arena) -> []u8 ! FsError

whole file into a new buffer in a

pub DirIter :: struct {
handle: i64,
namebuf: [1024]u8,
namelen: usize,
}

dir iteration; names include “.” and “..”, valid only until the next dir_next

pub open_dir :: fn(path: []const u8) -> DirIter ! FsError
pub dir_next :: fn(self: *DirIter) -> ?[]const u8

next entry name, or null at the end

pub dir_is_dir :: fn(self: *DirIter) -> bool

last entry is a dir

pub dir_size :: fn(self: *DirIter) -> u64

last entry’s size in bytes; always 0 on linux (stat the path)

pub dir_is_reparse :: fn(self: *DirIter) -> bool

last entry is a symlink/reparse point; skip these to avoid cycles

pub dir_close :: fn(self: *DirIter)
pub Info :: struct {
size: u64,
modified_ns: i64,
is_dir: bool,
}

result of info

  • size: bytes (0 for a folder on Linux and others)
  • modified_ns: last write, ns since the unix epoch
pub info :: fn(path: []const u8) -> Info ! FsError

size, mtime, kind of path; not_found if nothing is there

pub rename :: fn(from: []const u8, to: []const u8) -> void ! FsError

rename/move; replaces a file at to; rename_failed (missing, dir target, cross-volume)

pub write_file :: fn(path: []const u8, data: []const u8) -> void ! FsError

write data to path, created or truncated

pub copy_file :: fn(from: []const u8, to: []const u8) -> u64 ! FsError

copy a file, to created or truncated; returns bytes copied

pub Entry :: struct {
path: []const u8,
name: []const u8,
is_dir: bool,
depth: usize,
}

a walk entry

  • path: root + names below it, joined by “/”
  • name: the last part of path
  • depth: 1 for an entry of the root folder itself
pub Walker :: struct {
region: *Arena,
dirs: Vec(DirIter),
paths: Vec([]const u8),
failed: bool,
}

recursive walk, folders before their contents; links listed but not followed

  • dirs: the open folders, the innermost last
  • paths: their paths
pub next :: fn(self: *Self) -> ?Entry
pub close :: fn(self: *Self)

close what’s still open if the loop stops early

pub walk :: fn(a: *Arena, root: []const u8) -> Walker ! FsError

recursive walk; paths live in a

pub cwd :: fn(a: *Arena) -> []const u8 ! FsError

current folder, absolute, in a; not_found if removed or path too long

pub set_cwd :: fn(path: []const u8) -> void ! FsError

set the current folder, process-wide (all threads); not_found if not a folder

pub absolute :: fn(a: *Arena, p: []const u8) -> []const u8 ! FsError

absolute p in a via path::normalize; only cwd is read, so .. is lexical

pub temp_dir :: fn(a: *Arena) -> []const u8

temp folder, no trailing sep (windows: TMP, TEMP, USERPROFILE; else TMPDIR or /tmp)

pub home_dir :: fn(a: *Arena) -> ?[]const u8

USERPROFILE on windows, HOME elsewhere; null if unset

pub TempFile :: struct {
file: File,
path: []const u8,
}

from create_temp: the file, open to write, and its path

pub create_temp :: fn(a: *Arena, dir: []const u8, pattern: []const u8) -> TempFile ! FsError

new exclusive file in dir (“” = temp_dir()); last * of pattern -> 16 hex digits caller closes and deletes it; owner-only on linux; create_failed if no name worked

pub make_temp_dir :: fn(a: *Arena, dir: []const u8, pattern: []const u8) -> []const u8 ! FsError

new temp folder, named like create_temp; path in a; create_failed if none worked

pub remove_tree :: fn(path: []const u8) -> void ! FsError

delete a file or a whole folder tree; links are removed, not followed not_found if missing; delete_failed (open, read-only) after deleting what it could