Reading and writing whole files

The following procedures and syntax allow you to read and write the entire contents of a file, without iterating using a port.

Reading a file

For reading the contents of a file in a single operation, you can use the following syntax:

This is equivalent to using the path-data function (defined below):

(path-data &{named-literal-part+})

For example:

(define dir "/home/me/")
(define help-message &<{&[dir]HELP})

This binds help-message to the contents of the file named HELP in the dir directory.

Blobs

The content of a file is, in general, a sequence of uninterpreted bytes. Often these bytes represent text in a locale-dependent encoding, but we don’t always know this. Sometimes they’re images, or videos, or word-processor documents. A filename extension or a “magic number” in the file can give you hints, but not certainty as to the type of the data.

A blob is a raw uninterpreted sequence of bytes. It is a bytevector that can be automatically converted to other types as needed, specifically to a string or a bytevector.

The &<{..} returns a blob. For example, assume the file README contains (bytes representing) the text "Check doc directory.\n". Then:

#|kawa:1|# (define readme &<{README}))
|kawa:2|# readme:class
class gnu.lists.Blob
#|kawa:3|# (write (->string readme))
"Check doc directory.\n"
#|kawa:4|# (write (->bytevector readme))
#u8(67 104 101 99 107 32 100 111 99 32 100 105 114 101 99 116 111 114 121 46 10)
#|kawa:5|# (->bytevector readme):class
class gnu.lists.U8Vector

Writing to a file

The &<{..} syntax can be used with set! to replace the contents of a file:

(set! &<{README} "Check example.com\n")

The new contents must be blob-compatible - i.e. a bytevector or a string.

If you dislike using < as an output operator, you can instead using the &>{..} operation, which evaluates to a function whose single argument is the new value:

(&>{README} "Check example.com\n")

In general:

&>{named-literal-part+}

is equivalent to:

(lambda (new-contents)
  (set! &<{named-literal-part+} new-contents))

You can use &>> to append more data to a file:

(&>>{README} "or check example2.com\n")

Functions

Procedure: path-data path

Reads the contents of the file specified by path, where path can be a path object, or anything that can be converted to a Path, including a filename string or a URL. returning the result as a blob. The result is a blob, which is a kind of bytevector than can be auto-converted to a string or bytevecor as required.

The function path-data has a setter, which replaces the contents with new contents:

(set! &<{file-name} new-contents)

Procedure: path-bytes path

Reads the contents of the file specified by path, as with the path-data function, but the result is a plain bytevector, rather than a blob. This functtion also has a setter, which you can use to replace the file-contents by new bytevector-valued data.