LISP - 文件 I/O

我们已经讨论了通用 LISP 如何处理标准输入和输出。 所有这些函数也适用于读取和写入文本和二进制文件。 唯一的区别是,在这种情况下,我们使用的流不是标准输入或输出,而是为了写入或读取文件的特定目的而创建的流。

在本章中,我们将了解 LISP 如何创建、打开、关闭文本或二进制文件以存储数据。

文件代表字节序列,无论它是文本文件还是二进制文件。 本章将带您了解文件管理的重要函数/宏。

打开文件

您可以使用open函数创建新文件或打开现有文件。 这是打开文件最基本的功能。 但是,with-open-file 通常更方便且更常用,我们将在本节后面看到。

当打开一个文件时,会构造一个流对象来在 LISP 环境中表示它。 对流的所有操作基本上等同于对文件的操作。

open 函数的语法是 −

open filename &key :direction :element-type :if-exists :if-does-not-exist :external-format

其中,

  • filename 参数是要打开或创建的文件的名称。

  • key 参数指定流的类型和错误处理方式。

  • :direction 关键字指定流是否应处理输入、输出或两者,它采用以下值 −

    • :input - 用于输入流(默认值)

    • :output - 用于输出流

    • :io - 用于双向流

    • :probe - 用于仅检查文件是否存在; 流被打开然后关闭。

  • :element-type指定流的事务单元的类型。

  • :if-exists 参数指定当 :direction 为 :output 或 :io 并且指定名称的文件已存在时要采取的操作。 如果方向是 :input 或 :probe,则忽略此参数。 它采用以下值 −

    • :error - 表示错误。

    • :new-version - 它创建一个具有相同名称但版本号更大的新文件。

    • :rename - 重命名现有文件。

    • :rename-and-delete - 重命名现有文件,然后将其删除。

    • :append - 附加到现有文件。

    • :supersede - 它取代现有文件。

    • nil - 它不会创建文件,甚至不会创建流,只是返回 nil 来指示失败。

  • :if-does-not-exist 参数指定在指定名称的文件不存在时要采取的操作。 它采用以下值 −

    • :error - 表示错误。

    • :create - 它创建一个具有指定名称的空文件,然后使用它。

    • nil - 它不会创建文件甚至流,而只是返回 nil 来指示失败。

  • :external-format 参数指定用于表示文件中字符的实现识别方案。

例如,您可以打开存储在 /tmp 文件夹中名为 myfile.txt 的文件: −

(open "/tmp/myfile.txt")

写入和读取文件

with-open-file 允许使用与读/写事务关联的流变量来读取或写入文件。 作业完成后,它会自动关闭文件。 使用起来极其方便。

它具有以下语法 −

with-open-file (stream filename {options}*)
   {declaration}* {form}*
  • filename是要打开的文件名; 它可以是字符串、路径名或流。

  • options与函数 open 的关键字参数相同。

示例 1

创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。

(with-open-file (stream "/tmp/myfile.txt" :direction :output)
   (format stream "Welcome to Tutorials Point!")
   (terpri stream)
   (format stream "This is a tutorials database")
   (terpri stream)
   (format stream "Submit your Tutorials, White Papers and Articles into our Tutorials   Directory.")
)

请注意,上一章中讨论的所有输入输出函数(例如 terpri 和 format)都适用于写入我们在此处创建的文件。

当你执行代码时,它不会返回任何内容; 然而,我们的数据被写入文件中。 :direction :output 关键字允许我们做到这一点。

但是,我们可以使用read-line函数从此文件中读取内容。

示例 2

创建一个名为 main.lisp 的新源代码文件,并在其中键入以下代码。

(let ((in (open "/tmp/myfile.txt" :if-does-not-exist nil)))
   (when in
      (loop for line = (read-line in nil)
      
      while line do (format t "~a~%" line))
      (close in)
   )
)

执行代码时,会返回以下结果 −

Welcome to Tutorials Point!
This is a tutorials database
Submit your Tutorials, White Papers and Articles into our Tutorials Directory.

关闭文件

close 函数关闭流。