Filesystem


Quick Start

(module demo
  (import std.fs std.io)
  (begin
    ;; List the source tree
    (when (fs:directory? "examples")
      (for-each println (fs:list-directory "examples")))

    ;; Build a platform-correct path under the system temp dir
    (let ((p (fs:path-join (fs:temp-directory) "eta" "scratch.txt")))
      (println (fs:path-normalize p)))

    ;; Stat a file
    (when (fs:file-exists? "README.md")
      (println (fs:file-size "README.md"))
      (println (fs:file-modification-time "README.md")))))

std.fs is a thin Eta layer over the native filesystem builtins (file-exists?, path-join, temp-file, …). Paths are plain strings and use the platform-preferred separator on output (\ on Windows, / elsewhere).

It is auto-imported by std.prelude; importing it directly is also fine when you want a smaller surface:

(import std.fs)

API

Predicates and Stat

FunctionSignatureNotes
fs:file-exists?(path) -> boolTrue for any existing path (file, dir, symlink).
fs:directory?(path) -> boolTrue only for directories.
fs:file-size(path) -> intSize in bytes. Errors if the path is not a regular file.
fs:file-modification-time(path) -> intEpoch milliseconds, comparable with time:now-ms.

Mutation

FunctionSignatureNotes
fs:delete-file(path) -> '()Errors if the path is a directory. Use a separate recursive helper for trees.
fs:make-directory(path) -> '()Idempotent — succeeds if the directory already exists. Does not create parents.

Enumeration

FunctionSignatureNotes
fs:list-directory(path) -> listSorted list of entry names (no . / .., no leading path).

Paths

FunctionSignatureNotes
fs:path-join(seg1 seg2 ...) -> stringVariadic; joins with the platform separator.
fs:path-split(path) -> listInverse of fs:path-join — returns (root component …).
fs:path-normalize(path) -> stringLexical normalisation (a//b/../ca/c).

Temp Allocation

FunctionSignatureNotes
fs:temp-file() -> stringReserves a unique temp-file path under the system temp directory. The file is created empty.
fs:temp-directory() -> stringReserves and creates a unique temp directory.

Both helpers return absolute paths; cleanup is the caller’s responsibility (use fs:delete-file or platform tooling).


Patterns

Read-modify-write with a temp file

(import std.fs std.io)
(defun atomic-write (path text)
  (let ((tmp (fs:temp-file)))
    (with-output-to-port (open-output-file tmp)
      (lambda () (display text)))
    ;; On POSIX a rename would replace `path` atomically; on Windows
    ;; delete-file first if the destination exists.
    (when (fs:file-exists? path) (fs:delete-file path))
    (display "wrote ") (display tmp) (newline)))

Walk a directory tree

(defun walk (root visit)
  (visit root)
  (when (fs:directory? root)
    (for-each
      (lambda (name) (walk (fs:path-join root name) visit))
      (fs:list-directory root))))

Build platform-correct paths from segments

(define cache-dir (fs:path-join (or (os:getenv "XDG_CACHE_HOME")
                                    (fs:path-join (os:getenv "HOME") ".cache"))
                                "eta"))
(fs:make-directory cache-dir)

Notes