输入缺省是从 流读取。输出缺省是在 *standard-output* 流。最初它们大概会在相同的地方:一个表示顶层的流。

    我们已经看过 readformat 是如何在顶层读取与印出。前者接受一个应是流的选择性参数,缺省是 *standard-input*format 的第一个参数也可以是一个流,但当它是 t 时,输出被送到 *standard-output* 。所以我们目前为止都只用到缺省的流而已。我们可以在任何流上面做同样的 I/O 操作。

    路径名(pathname)是一种指定一个文件的可移植方式。路径名包含了六个部分:host、device、directory、name、type 及 version。你可以通过调用 make-pathname 搭配一个或多个对应的关键字参数来产生一个路径。在最简单的情况下,你可以只指明名字,让其他的部分留为缺省:

    开启一个文件的基本函数是 open 。它接受一个路径名 以及大量的选择性关键字参数,而若是开启成功时,返回一个指向文件的流。

    1. > (setf str (open path :direction :output
    2. :if-exists :supersede))

    流的打印表示法因实现而异。

    现在我们可以把这个流作为第一个参数传给 format ,它会在流印出,而不是顶层:

    如果我们在此时检查这个文件,可能有输出,也可能没有。某些实现会将输出累积成一块 (chunks)再输出。直到我们将流关闭,它也许一直不会出现:

    1. > (close str)
    2. NIL

    当你使用完时,永远记得关闭文件;在你还没关闭之前,内容是不保证会出现的。现在如果我们检查文件 “myfile” ,应该有一行:

    1. #<Stream C01C86>

    我们可以对一个文件使用任何输入函数。7.2 节会更详细的描述输入。这里作为一个示例,我们将使用 read-line 从文件来读取一行文字:

    当你读取完毕时,记得关闭文件。

    大部分时间我们不使用 openclose 来操作文件的 I/O 。 with-open-file 宏通常更方便。它的第一个参数应该是一个列表,包含了变数名、伴随着你想传给 open 的参数。在这之后,它接受一个代码主体,它会被绑定至流的变数一起被求值,其中流是通过将剩余的参数传给 open 来创建的。之后这个流会被自动关闭。所以整个文件写入动作可以表示为:

    1. (with-open-file (str path :direction :output
    2. (format str "Something~%"))

    with-open-file 宏将 放在 unwind-protect 里 (参见 92 页,译注: 5.6 节),即使一个错误打断了主体的求值,文件是保证会被关闭的。