file

List of symbols:

cd, fclose, fflush, fopen, fs-accessed, fs-base, fs-crawl, fs-dir?, fs-exists?, fs-file?, fs-len, fs-modified, fs-parent, fs-rm, fs-same?, get-temp, get-temp-file, glob, read, read-all, read-line, temp-dir, with-temp, with-temp-file

cd

Usage: (cd dir-to-change-to)

Change directory.

Example:

(with-temp (fn (tmp)
(fclose (fopen (str tmp "/fs-cd-marker") :create :truncate))
(test::assert-false (fs-exists? "fs-cd-marker"))
(cd tmp)
(test::assert-true (fs-exists? "fs-cd-marker"))
(cd)))

fclose

Usage: (fclose file)

Close a file.

Example:

(with-temp-file (fn (tmp-file)
    (let (tst-file (fopen tmp-file :create :truncate))
        (fprn tst-file "Test Line Two")
        (fclose tst-file)
        (set! tst-file (fopen tmp-file :read))
        (defer (fclose tst-file))
        (test::assert-equal "Test Line Two
" (read-line tst-file)))))

fflush

Usage: (flush file)

Flush a file.

Example:

(with-temp-file (fn (tmp-file)
    (let (tst-file (fopen tmp-file :create :truncate)
          tst-file-read (fopen tmp-file :read))
        (defer (fclose tst-file))
        (defer (fclose tst-file-read))
        (fprn tst-file "Test Line Three")
        (fflush tst-file)
        (test::assert-equal "Test Line Three
" (read-line tst-file-read)))))

fopen

Usage: (fopen filename option*)

Open a file. If you use :read and :write then you get a read/write unbuffered file. Including one of :read or :write will provide a file buffered for read or write (this is faster). Note: :append, :truncate, :create, :create-new all imply :write.

Options are: :read :write :append :truncate :create :create-new :on-error-nil

Example:

(with-temp-file (fn (tmp-file)
    (let (test-open-f (fopen tmp-file :create :truncate))
        (fprn test-open-f "Test Line One")
        (fclose test-open-f)
        (set! test-open-f (fopen tmp-file :read))
        (defer (fclose test-open-f))
        (test::assert-equal "Test Line One
" (read-line test-open-f)))))

fs-accessed

Usage: (fs-accessed /path/to/file/or/dir)

Returns the unix time file last accessed in ms.

Example:

(with-temp-file (fn (tmp)
(let (tst-file (fopen tmp :create)
last-acc (fs-accessed tmp))
(fclose tst-file)
(let (tst-file (fopen tmp :read))
(test::assert-true (>= (fs-accessed tmp) last-acc))
(fclose tst-file)))))

fs-base

Usage: (fs-base /path/to/file/or/dir)

Returns base name of file or directory passed to function.

No Examples

fs-crawl

Usage: (fs-crawl /path/to/file/or/dir (fn (x) (prn "found path" x) [max-depth] [:follow-syms])

If a directory is provided the path is recursively searched and every file and directory is called as an argument to the provided function. If a file is provided the path is provided as an argument to the provided function. Takes two optional arguments (in any order) an integer, representing max depth to traverse if file is a directory, or the symbol, :follow-syms, to follow symbol links when traversing if desired.

Example:

(with-temp-file (fn (tmp-file)
(let (cnt 0)
(fs-crawl tmp-file (fn (x)
(test::assert-equal (fs-base tmp-file) (fs-base x))
(set! cnt (+ 1 cnt))))
(test::assert-equal 1 cnt))))


(defn create-in (in-dir num-files visited)
(dotimes-i i num-files
(let (tmp-file (get-temp-file in-dir))
(set! visited.~tmp-file #f))))

(defn create-dir (tmp-dir visited)
(let (new-tmp (get-temp tmp-dir))
(set! visited.~new-tmp #f)
new-tmp))

(with-temp (fn (root-tmp-dir)
(let (tmp-file-count 5
visited {}
cnt 0)
(set! visited.~root-tmp-dir #f)
(create-in root-tmp-dir tmp-file-count visited)
(let (tmp-dir (create-dir root-tmp-dir visited)
new-files (create-in tmp-dir tmp-file-count visited)
tmp-dir (create-dir tmp-dir visited)
new-files (create-in tmp-dir tmp-file-count visited))
(fs-crawl root-tmp-dir (fn (x)
(let (file visited.~x)
(test::assert-true (not file)) ;; also tests double counting
(set! visited.~x #t)
(inc! cnt))))
(test::assert-equal (+ 3 (* 3 tmp-file-count)) cnt)
(test::assert-equal (+ 3 (* 3 tmp-file-count)) (len visited))
(seq-for key in (hash-keys visited) (test::assert-true visited.~key))))))

(with-temp (fn (root-tmp-dir)
(let (tmp-file-count 5
visited {}
cnt 0)
(set! visited.~root-tmp-dir #f)
(create-in root-tmp-dir tmp-file-count visited)
(let (tmp-dir (create-dir root-tmp-dir visited)
new-files (create-in tmp-dir tmp-file-count visited)
tmp-dir (create-dir tmp-dir {})
new-files (do (set! visited.~tmp-dir #f)(create-in tmp-dir tmp-file-count {})))
(fs-crawl root-tmp-dir (fn (x)
(let (file visited.~x)
(test::assert-true (not file)) ;; also tests double counting
(set! visited.~x #t)
(inc! cnt))) 2)
(test::assert-equal (+ 3 (* 2 tmp-file-count)) cnt)
(test::assert-equal (+ 3 (* 2 tmp-file-count)) (len visited))
(seq-for key in (hash-keys visited) (test::assert-true visited.~key))))))

(with-temp (fn (root-tmp-dir)
(let (tmp-file-count 5
visited {}
cnt 0)
(set! visited.~root-tmp-dir #f)
(create-in root-tmp-dir tmp-file-count visited)
(let (tmp-dir (create-dir root-tmp-dir {})
new-files (do (set! visited.~tmp-dir #f)(create-in tmp-dir tmp-file-count {}))
tmp-dir (create-dir tmp-dir {})
new-files (create-in tmp-dir tmp-file-count {}))
(fs-crawl root-tmp-dir (fn (x)
(let (file visited.~x)
(test::assert-true (not file)) ;; also tests double counting
(set! visited.~x #t)
(inc! cnt))) 1)
(test::assert-equal (+ 2 tmp-file-count) cnt)
(test::assert-equal (+ 2 tmp-file-count) (len visited))
(seq-for key in (hash-keys visited) (test::assert-true visited.~key))))))

fs-dir?

Usage: (fs-dir? path-to-test)

Is the given path a directory?

Example:

(with-temp (fn (tmp)
(fclose (fopen (str tmp "/fs-dir-file") :create :truncate))
(test::assert-false (fs-dir? (str tmp "/fs-dir-file")))
(test::assert-true (fs-dir? tmp))
(test::assert-false (fs-file? (str tmp "/fs-dir-nope")))))

fs-exists?

Usage: (fs-exists? path-to-test)

Does the given path exist?

Example:

(with-temp (fn (tmp)
(fclose (fopen (str tmp "/fs-exists") :create :truncate))
(test::assert-true (fs-exists? (str tmp "/fs-exists")))
(test::assert-true (fs-exists? tmp))
(test::assert-false (fs-exists? (str tmp "/fs-exists-nope")))))

fs-file?

Usage: (fs-file? path-to-test)

Is the given path a file?

Example:

(with-temp (fn (tmp)
(fclose (fopen (str tmp "/fs-file") :create :truncate))
(test::assert-true (fs-file? (str tmp "/fs-file")))
(test::assert-false (fs-file? tmp))
(test::assert-false (fs-file? (str tmp "/fs-file-nope")))))

fs-len

Usage: (fs-len /path/to/file/or/dir)

Returns the size of the file in bytes.

Example:

(with-temp-file (fn (tmp)
(let (tst-file (fopen tmp :create :truncate))
(fprn tst-file "Test Line Read Line One")
(fpr tst-file "Test Line Read Line Two")
(fclose tst-file)
(test::assert-equal 47 (fs-len tmp)))))

fs-modified

Usage: (fs-modified /path/to/file/or/dir)

Returns the unix time file last modified in ms.

Example:

(with-temp-file (fn (tmp)
(let (tst-file (fopen tmp :create :truncate)
last-mod (fs-modified tmp))
(fprn tst-file "Test Line Read Line One")
(fpr tst-file "Test Line Read Line Two")
(fflush tst-file)
(fclose tst-file)
(test::assert-true (>= (fs-modified tmp) last-mod)))))

fs-parent

Usage: (fs-parent /path/to/file/or/dir)

Returns base name of file or directory passed to function.

No Examples

fs-rm

Usage: (fs-rm "/dir/or/file/to/remove")

Takes a file or directory as a string and removes it. Works recursively for directories.

Example:

(def fp nil)
(let (a-file (get-temp-file))
(test::assert-true (fs-exists? a-file))
(set! fp a-file)
(fs-rm a-file))
(test::assert-false (nil? fp))
(test::assert-false (fs-exists? fp))

fs-same?

Usage: (fs-same? /path/to/file/or/dir /path/to/file/or/dir)

Returns true if the two provided file paths refer to the same file or directory.

Example:

(with-temp-file (fn (tmp-file)
(test::assert-true (fs-same? tmp-file tmp-file))))

get-temp

Usage: (get-temp ["/path/to/directory/to/use/as/base" "optional-prefix" "optional-suffix" length])

Creates a directory inside of an OS specific temporary directory. See temp-dir for OS specific notes. Also accepts an optional prefix, an optional suffix, and an optional length for the random number of characters in the temporary file created. Defaults to prefix of ".tmp", no suffix, and five random characters.

Example:

(test::assert-true (str-contains (get-temp) (temp-dir)))

(with-temp (fn (tmp)
(let (tmp-dir (get-temp tmp))
(test::assert-true (str-contains tmp-dir tmp)))))

(with-temp (fn (tmp)
(let (tmp-dir (get-temp tmp "some-prefix"))
(test::assert-true (str-contains tmp-dir tmp))
(test::assert-true (str-contains tmp-dir "some-prefix")))))

(with-temp (fn (tmp)
(let (tmp-dir (get-temp tmp "some-prefix" "some-suffix"))
(test::assert-true (str-contains tmp-dir tmp))
(test::assert-true (str-contains tmp-dir "some-prefix"))
(test::assert-true (str-contains tmp-dir "some-suffix")))))

(with-temp (fn (tmp)
(let (tmp-dir (get-temp tmp "some-prefix" "some-suffix" 6))
(test::assert-true (str-contains tmp-dir tmp))
(test::assert-true (str-contains tmp-dir "some-prefix"))
(test::assert-true (str-contains tmp-dir "some-suffix"))
(test::assert-equal (len "some-prefix012345some-suffix") (len (fs-base tmp-dir))))))

get-temp-file

Usage: (get-temp-file ["/path/to/directory/to/use/as/base" "optional-prefix" "optional-suffix" length])

Returns name of file created inside temporary directory. Optionally takes a directory to use as the parent directory of the temporary file. Also accepts an optional prefix, an optional suffix, and an optional length for the random number of characters in the temporary files created. Defaults to prefix of ".tmp", no suffix, and five random characters.

Example:

(test::assert-true (str-contains (get-temp-file) (temp-dir)))

(with-temp (fn (tmp)
(let (tmp-file (get-temp-file tmp))
(test::assert-true (str-contains tmp-file tmp)))))

(with-temp (fn (tmp)
(let (tmp-file (get-temp-file tmp "some-prefix"))
(test::assert-true (str-contains tmp-file "some-prefix")))))

(with-temp (fn (tmp)
(let (tmp-file (get-temp-file tmp "some-prefix" "some-suffix"))
(test::assert-true (str-contains tmp-file "some-prefix"))
(test::assert-true (str-contains tmp-file "some-suffix")))))

(with-temp (fn (tmp)
(let (tmp-file (get-temp-file tmp "some-prefix" "some-suffix" 10))
(test::assert-true (str-contains tmp-file "some-prefix"))
(test::assert-true (str-contains tmp-file "some-suffix"))
(test::assert-equal (len "some-prefix0123456789some-suffix") (len (fs-base tmp-file))))))

glob

Usage: (glob /path/with/*)

Takes a list/varargs of globs and return the list of them expanded.

Example:

(with-temp (fn (tmp)
(fclose (fopen (str tmp "/g1") :create :truncate))
(fclose (fopen (str tmp "/g2") :create :truncate))
(fclose (fopen (str tmp "/g3") :create :truncate))
(test::assert-equal [(str tmp "/g1") (str tmp "/g2") (str tmp "/g3")] (glob (str tmp "/*")))))

read

Usage: (read file|string end-exp?) -> expression

Read a file or string and return the next object (symbol, string, list, etc). Raises an error if the file or string has been read unless end-exp is provided then returns that on the end condition. Note: When reading a string read always starts at the beginning of the string.

Example:

(with-temp-file (fn (tmp)
    (let (tst-file (fopen tmp :create :truncate)
          test-str nil)
        (fprn tst-file "(1 2 3)(x y z)")
        (fclose tst-file)
        (set! tst-file (fopen tmp :read))
        (test::assert-equal '(1 2 3) (read tst-file))
        (test::assert-equal '(x y z) (read tst-file))
        (test::assert-error (read tst-file))
        (fclose tst-file)
        (set! tst-file (fopen tmp :read))
        (test::assert-equal '(1 2 3) (read tst-file :done))
        (test::assert-equal '(x y z) (read tst-file :done))
        (test::assert-equal :done (read tst-file :done))
        (fclose tst-file)
        (test::assert-equal '(4 5 6) (read "(4 5 6)"))
        (set! test-str "7 8 9")
        (test::assert-equal 7 (read test-str))
        (test::assert-equal 7 (read test-str))
        (test::assert-equal '(x y z) (read "(x y z)")))))

read-all

Usage: (read-all file|string) -> vec

Read a file or string and return the vector of contained expressions. This reads the entire file or string and will wrap it in an outer vector (always returns a vector).

Unlike most lisp readers this one will put loose symbols in a vector (i.e. you enter things at the repl without the enclosing parens).

If the read item is empty (including a comment) then will return an empty vector.

Example:

(with-temp-file (fn (tmp)
    (let (tst-file (fopen tmp :create :truncate)
          test-str nil)
        (fprn tst-file "(1 2 3)(x y z)")
        (fclose tst-file)
        (set! tst-file (fopen tmp :read))
        (test::assert-equal ['(1 2 3)'(x y z)] (read-all tst-file))
        (fclose tst-file)
        (test::assert-equal ['(4 5 6)] (read-all "(4 5 6)"))
        (test::assert-equal [7 8 9] (read-all "7 8 9"))
        (test::assert-equal ['(x y z)] (read-all "(x y z)"))
        (test::assert-equal [] (read-all ";(x y z)")))))

read-line

Usage: (read-line file) -> string

Read a line from a file. Returns Nil if there is nothing left to read.

Example:

(with-temp-file (fn (tmp)
    (let (tst-file (fopen tmp :create :truncate))
        (fprn tst-file "Test Line Read Line One")
        (fpr tst-file "Test Line Read Line Two")
        (fclose tst-file)
        (set! tst-file (fopen tmp :read))
        (defer (fclose tst-file))
        (test::assert-equal "Test Line Read Line One\n" (read-line tst-file))
        (test::assert-equal "Test Line Read Line Two" (read-line tst-file)))))

temp-dir

Usage: (temp-dir)

Returns a string representing the temporary directory. See get-temp for higher level temporary directory creation mechanism.

On Unix: Returns the value of the TMPDIR environment variable if it is set, otherwise for non-Android it returns /tmp. If Android, since there is no global temporary folder (it is usually allocated per-app), it returns /data/local/tmp.

On Windows: Returns the value of, in order, the TMP, TEMP, USERPROFILE environment variable if any are set and not the empty string. Otherwise, temp_dir returns the path of the Windows directory. This behavior is identical to that of GetTempPath, which this function uses internally.

Example:

(test::assert-true (fs-dir? (temp-dir)))

with-temp

Usage: (with-temp (fn (x) (println "given temp dir:" x)) ["optional-prefix" "optional-suffix" length])

Takes a function that accepts a temporary directory. This directory will be recursively removed when the provided function is finished executing. Also accepts an optional prefix, an optional suffix, and an optional length for the random number of characters in the temporary directory created. Defaults to prefix of ".tmp", no suffix, and five random characters.

Example:

(def fp nil)
(with-temp (fn (tmp-dir)
    (let (tmp-file (str tmp-dir "/sl-sh-tmp-file.txt")
         a-file (fopen tmp-file :create :truncate))
        (test::assert-true (fs-exists? tmp-file))
        (set! fp tmp-file)
        (fclose a-file))))
(test::assert-false (nil? fp))
(test::assert-false (fs-exists? fp))

(with-temp
    (fn (tmp)
        (test::assert-true (str-contains tmp "some-prefix")))
    "some-prefix")

(with-temp
    (fn (tmp)
        (test::assert-true (str-contains tmp "some-prefix"))
        (test::assert-true (str-contains tmp "some-suffix")))
    "some-prefix"
    "some-suffix")

(with-temp
    (fn (tmp)
        (test::assert-true (str-contains tmp "some-prefix"))
        (test::assert-true (str-contains tmp "some-suffix"))
        (test::assert-equal (len "some-prefix0123456789some-suffix") (len (fs-base tmp))))
    "some-prefix"
    "some-suffix"
    10)

with-temp-file

Usage: (with-temp-file (fn (x) (println "given temp file:" x)) ["optional-prefix" "optional-suffix" length])

Takes a function that accepts a temporary file. This file will be removed when the provided function is finished executing. Also accepts an optional prefix, an optional suffix, and an optional length for the random number of characters in the temporary file created. Defaults to prefix of ".tmp", no suffix, and five random characters.

Example:

(def fp nil)
(with-temp-file (fn (tmp-file)
    (let (a-file (fopen tmp-file :create :truncate))
        (test::assert-true (fs-exists? tmp-file))
        (set! fp tmp-file)
        (fclose a-file))))
(test::assert-false (nil? fp))
(test::assert-false (fs-exists? fp))

(with-temp-file
    (fn (tmp)
        (test::assert-true (str-contains tmp "some-prefix")))
    "some-prefix")

(with-temp-file
    (fn (tmp)
        (test::assert-true (str-contains tmp "some-prefix"))
        (test::assert-true (str-contains tmp "some-suffix")))
    "some-prefix"
    "some-suffix")

(with-temp-file
    (fn (tmp)
        (test::assert-true (str-contains tmp "some-prefix"))
        (test::assert-true (str-contains tmp "some-suffix"))
        (test::assert-equal (len "some-prefix0123456789some-suffix") (len (fs-base tmp))))
    "some-prefix"
    "some-suffix"
    10)