LISP - 檔案 I/O



我們已經討論了 Common LISP 如何處理標準輸入和輸出。所有這些函式也適用於讀取和寫入文字檔案和二進位制檔案。唯一的區別在於,在這種情況下,我們使用的流不是標準輸入或輸出,而是為寫入或讀取檔案而建立的流。

在本章中,我們將瞭解 LISP 如何建立、開啟、關閉文字檔案或二進位制檔案以進行資料儲存。

檔案表示一系列位元組,無論它是文字檔案還是二進位制檔案。本章將引導您瞭解檔案管理的重要函式/宏。

開啟檔案

您可以使用 **open** 函式建立新檔案或開啟現有檔案。它是開啟檔案的最基本函式。但是,**with-open-file** 通常更方便且更常用,我們將在本節後面看到。

開啟檔案時,會構造一個流物件來在 LISP 環境中表示它。對流的所有操作基本上等同於對檔案進行的操作。

**open** 函式的語法為:

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

其中:

  • filename 引數是要開啟或建立的檔案的名稱。

  • keyword 引數指定流的型別和錯誤處理方式。

  • **: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** 引數指定實現識別的用於表示檔案中的字元的方案。

例如,您可以開啟名為 myfile.txt 的檔案,該檔案儲存在 /tmp 資料夾中,如下所示:

(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** 函式關閉流。

廣告
© . All rights reserved.