File
A simple file abstraction for Carp.
Installation
You can obtain this library like so:
(load "git@github.com:carpentry-org/file@0.4.0")
Usage
The main type involved in working with this library is File, naturally. All
file operations depend on the file being opened.
; returns a Result containing a File you can write to
(File.open "example.txt")
; returns a Result containing a File you append to
(File.open-with "example.txt" "a")
If the file couldn’t be opened due to it not existing or file permission errors,
a Result.Error with an error message is returned.
The file permissions follow the file modes
in UNIX. The default is "a+", or writing/reading. Generally, files have a
name, mode, and file property; you can read safely from them, but writing
to them directly is discouraged.
Before you end your operations on the file, it is good practice to close the
file again. In Carp, we do this using close.
(close f)
You can read from the file—or read-all, if you don’t care about length—,
write to it, remove it, or rewind the file buffer.
(write &f "hi")
(rewind &f)
(IO.println &(read-all &f))
All of these will check whether the files are actually readable and/or writable
before performing any IO actions and return a Result.Error if they can’t.
A successful write only means the data reached the standard library’s buffer,
though, so the write can still fail when that buffer is handed to the operating
system. close throws that final status away; close-checked returns it, and
flush forces the buffer out early so a caller can check before closing.
(flush &f)
(close-checked f)
Reading is all-or-nothing: asking read for more values than the file holds is
a Result.Error, never a short result. read-all seeks to find the length, so
unseekable inputs such as pipes and terminals are an error as well.
When a short read is expected rather than a failure—reading a file in chunks,
say—ByteReader.read-at-most returns however many bytes were there.
You can also ask about the modes of the file, using the functions readable?,
writable?, or binary-mode?.
binary-mode?
(Fn [(Ref File a)] Bool)
(binary-mode? f)
checks whether a file is in binary mode by examining its mode.
close
(Fn [File] ())
(close f)
closes a file and takes ownership.
Discards the status of the close; use
close-checked to receive it.
close-checked
(Fn [File] (Result () String))
(close-checked f)
closes a file and takes ownership, reporting failure.
Returns a result containing either nothing, or an error if the buffered data couldn’t be flushed while closing, or if a read, a write or a flush on the file had already failed earlier—in which case the error names that earlier failure rather than the close. The file is closed either way.
close does the same but discards that result.
contents
(Fn [(Ref String a)] (Result (Array String) String))
(contents s)
walks a directory with the default walk mode (see also
default-walk).
Returns a result containing either the contents of that directory or an error if a directory couldn’t be opened due to permission errors or if the user tried to open a non-existent directory.
contents-with
(Fn [(Ref String a), (Ref WalkOptions b)] (Result (Array String) String))
(contents-with s options)
walks a directory with a custom walk mode.
Returns a result containing either the directory contents or an error if a directory couldn’t be opened due to permission errors or if the user tried to open a non-existent directory.
default-walk
WalkOptions
is the default options used by walk.
Initially set to recursive, not following links, and not matching directories or dotfiles.
flush
(Fn [(Ref File a)] (Result () String))
(flush f)
flushes a file’s buffered writes out to the operating system.
Returns a result containing either nothing, or an error if the buffered data couldn’t be written—because the disk is full, say.
Since write returns as soon as the data is buffered, this is the
earliest point at which a caller can tell that a write really landed.
The error is sticky: once a read, a write or a flush on the file has failed, every later flush reports an error too, even though this flush itself had nothing left to do. Those later errors name that earlier failure rather than this flush.
map
(Fn [(Ref String a), (Ref (Fn [(Ref String b)] c d) e)] (Result (Array c) String))
(map s callback)
walks a directory with the default walk mode (see also
default-walk).
Returns a result containing either the results of the walker function as an array or an error if a directory couldn’t be opened due to permission errors or if the user tried to open a non-existent directory.
map-with
(Fn [(Ref String a), (Ref (Fn [(Ref String b)] c d) e), (Ref WalkOptions f)] (Result (Array c) String))
(map-with s callback options)
walks a directory with a custom walk mode.
Returns a result containing either the results of the walker function as an array or an error if a directory couldn’t be opened due to permission errors or if the user tried to open a non-existent directory.
open
(Fn [(Ref String a)] (Result File String))
(open name)
opens a file with the default file mode (see also
default-mode).
Returns a result containing either a file, or an error if the file couldn’t be opened due to permission errors or if the user tried to read from a non-existent file.
open-with
(Fn [(Ref String a), (Ref String b)] (Result File String))
(open-with name mode)
opens a file with custom file mode.
Returns a result containing either a file, or an error if the file couldn’t be opened due to permission errors or if the user tried to read from a non-existent file.
read
(Fn [(Ref File a), Int] (Result b String))
(read f len)
Reads exactly len values from a file.
A read is all-or-nothing: if the file holds fewer than len values, the values that were read are discarded and a Result.Error naming how many were available is returned. A negative len is an error too.
This function is generic in its return argument. You can provide a custom reader implementation by implementing the read-from-file interface.
The surrounding context typically determine's the return type.if no implementation of read-from-file exists for the type, you'll need to provide one. You can also use the to specify the return type.
For example (to read the first 3 bytes of the file):
(match (File.open-with "test-file.txt" "r")
(Result.Success f) (the (Result (Array Byte) String) (File.read &f 3))
(Result.Error x) (Result.Error x))))
read-all
(Fn [(Ref File a)] (Result b String))
(read-all f)
reads the entire file content of a file.
Returns a result containing the string on success and an error if the file is not readable.
The length is determined by seeking, so unseekable inputs such as pipes and terminals return an error rather than their contents.
readable?
(Fn [(Ref File a)] Bool)
(readable? f)
checks whether a file is readable by examining its mode.
remove
(Fn [(Ref File a)] (Result () String))
(remove f)
removes a file from the file system.
Returns a result containing either nothing, or an error if the file couldn’t be removed—because it is already gone or its directory isn’t writable, say.
walk
(Fn [(Ref String a), (Ref (Fn [(Ref String b)] () c) d)] (Result Int String))
(walk s callback)
walks a directory with the default walk mode (see also
default-walk).
Returns a result containing either nothing, or an error if a directory couldn’t be opened due to permission errors or if the user tried to open a non-existent directory.
The walk aborts at the first subdirectory it can’t descend into and returns that error, so a success means the entire tree was visited.
walk-mode
(Fn [Bool, Bool, Bool, Bool] WalkOptions)
(walk-mode recursive? follow-links? dotfiles? match-dirs?)
constructs a mode for walk-with.
walk-with
(Fn [(Ref String a), (Ref (Fn [(Ref String b)] () c) d), (Ref WalkOptions e)] (Result Int String))
(walk-with s callback options)
walks a directory with a custom walk mode.
Returns a result containing either nothing, or an error if a directory couldn’t be opened due to permission errors or if the user tried to open a non-existent directory.
The walk aborts at the first subdirectory it can’t descend into and returns that error, so a success means the entire tree was visited.
writable?
(Fn [(Ref File a)] Bool)
(writable? f)
checks whether a file is writable by examining its mode.
write
(Fn [(Ref File a), b] (Result Int String))
(write f obj)
Writes a value to a file.
This function is generic in its input. You can provide a custom reader implementation by implementing the write-to-file interface