输入缺省是从 流读取。输出缺省是在 *standard-output*
流。最初它们大概会在相同的地方:一个表示顶层的流。
我们已经看过 read
与 format
是如何在顶层读取与印出。前者接受一个应是流的选择性参数,缺省是 *standard-input*
。 format
的第一个参数也可以是一个流,但当它是 t
时,输出被送到 *standard-output*
。所以我们目前为止都只用到缺省的流而已。我们可以在任何流上面做同样的 I/O 操作。
路径名(pathname)是一种指定一个文件的可移植方式。路径名包含了六个部分:host、device、directory、name、type 及 version。你可以通过调用 make-pathname
搭配一个或多个对应的关键字参数来产生一个路径。在最简单的情况下,你可以只指明名字,让其他的部分留为缺省:
开启一个文件的基本函数是 open
。它接受一个路径名 以及大量的选择性关键字参数,而若是开启成功时,返回一个指向文件的流。
> (setf str (open path :direction :output
:if-exists :supersede))
流的打印表示法因实现而异。
现在我们可以把这个流作为第一个参数传给 format
,它会在流印出,而不是顶层:
如果我们在此时检查这个文件,可能有输出,也可能没有。某些实现会将输出累积成一块 (chunks)再输出。直到我们将流关闭,它也许一直不会出现:
> (close str)
NIL
当你使用完时,永远记得关闭文件;在你还没关闭之前,内容是不保证会出现的。现在如果我们检查文件 “myfile” ,应该有一行:
#<Stream C01C86>
我们可以对一个文件使用任何输入函数。7.2 节会更详细的描述输入。这里作为一个示例,我们将使用 read-line
从文件来读取一行文字:
当你读取完毕时,记得关闭文件。
大部分时间我们不使用 open
与 close
来操作文件的 I/O 。 with-open-file
宏通常更方便。它的第一个参数应该是一个列表,包含了变数名、伴随着你想传给 open
的参数。在这之后,它接受一个代码主体,它会被绑定至流的变数一起被求值,其中流是通过将剩余的参数传给 open
来创建的。之后这个流会被自动关闭。所以整个文件写入动作可以表示为:
(with-open-file (str path :direction :output
(format str "Something~%"))
with-open-file
宏将 放在 unwind-protect
里 (参见 92 页,译注: 5.6 节),即使一个错误打断了主体的求值,文件是保证会被关闭的。