LISP - Tệp I / O
Chúng ta đã thảo luận về cách xử lý đầu vào và đầu ra tiêu chuẩn của LISP chung. Tất cả các hàm này cũng hoạt động để đọc và ghi vào văn bản và tệp nhị phân. Chỉ khác là trong trường hợp này, luồng chúng tôi sử dụng không phải là đầu vào hoặc đầu ra tiêu chuẩn, mà là luồng được tạo cho mục đích cụ thể để ghi vào hoặc đọc từ tệp.
Trong chương này, chúng ta sẽ xem cách LISP có thể tạo, mở, đóng các tệp văn bản hoặc tệp nhị phân để lưu trữ dữ liệu của chúng.
Tệp đại diện cho một chuỗi các byte, không quan trọng đó là tệp văn bản hay tệp nhị phân. Chương này sẽ đưa bạn qua các chức năng / macro quan trọng để quản lý tệp.
Mở tệp
Bạn có thể dùng openchức năng tạo tệp mới hoặc mở tệp hiện có. Đây là chức năng cơ bản nhất để mở tệp. Tuy nhiên,with-open-file thường thuận tiện hơn và được sử dụng phổ biến hơn, như chúng ta sẽ thấy ở phần sau của phần này.
Khi một tệp được mở, một đối tượng luồng được xây dựng để đại diện cho nó trong môi trường LISP. Tất cả các thao tác trên luồng về cơ bản tương đương với các thao tác trên tệp.
Cú pháp cho open chức năng là -
open filename &key :direction :element-type :if-exists :if-does-not-exist :external-format
Ở đâu,
Đối số tên tệp là tên của tệp sẽ được mở hoặc tạo.
Các đối số từ khóa chỉ định loại luồng và các cách xử lý lỗi.
Các :direction từ khóa chỉ định liệu luồng sẽ xử lý đầu vào, đầu ra hay cả hai, nó nhận các giá trị sau:
: input - cho các luồng đầu vào (giá trị mặc định)
: output - cho các luồng đầu ra
: io - cho luồng hai chiều
: probe - chỉ để kiểm tra sự tồn tại của tệp; luồng được mở và sau đó đóng lại.
Các :element-type chỉ định loại đơn vị giao dịch cho luồng.
Các :if-existsđối số chỉ định hành động được thực hiện nếu: hướng là: đầu ra hoặc: io và tệp có tên được chỉ định đã tồn tại. Nếu hướng là: input hoặc: probe, thì đối số này bị bỏ qua. Nó có các giá trị sau:
: error - nó báo hiệu một lỗi.
: new-version - nó tạo một tệp mới có cùng tên nhưng số phiên bản lớn hơn.
: rename - nó đổi tên tệp hiện có.
: rename-and-delete - nó đổi tên tệp hiện có và sau đó xóa nó.
: append - nó gắn vào tệp hiện có.
: supersede - nó thay thế tệp hiện có.
nil - nó không tạo một tệp hoặc thậm chí một luồng chỉ trả về nil để chỉ ra sự thất bại.
Các :if-does-not-existđối số chỉ định hành động sẽ được thực hiện nếu tệp có tên được chỉ định chưa tồn tại. Nó có các giá trị sau:
: error - nó báo hiệu một lỗi.
: create - nó tạo một tệp trống với tên được chỉ định và sau đó sử dụng nó.
nil - nó không tạo một tệp hoặc thậm chí một luồng, mà thay vào đó chỉ trả về nil để chỉ ra sự thất bại.
Các :external-format đối số chỉ định một lược đồ được triển khai công nhận để biểu diễn các ký tự trong tệp.
Ví dụ: bạn có thể mở một tệp có tên myfile.txt được lưu trữ trong thư mục / tmp dưới dạng -
(open "/tmp/myfile.txt")
Ghi và đọc từ tệp
Các with-open-filecho phép đọc hoặc ghi vào một tệp, sử dụng biến luồng được liên kết với giao dịch đọc / ghi. Sau khi hoàn thành công việc, nó sẽ tự động đóng tệp. Nó là vô cùng thuận tiện để sử dụng.
Nó có cú pháp sau:
with-open-file (stream filename {options}*)
{declaration}* {form}*
tên tệp là tên của tệp sẽ được mở; nó có thể là một chuỗi, một tên đường dẫn hoặc một luồng.
Các tùy chọn giống như các đối số từ khóa cho hàm đang mở.
ví dụ 1
Tạo một tệp mã nguồn mới có tên main.lisp và nhập mã sau vào đó.
(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.")
)
Xin lưu ý rằng tất cả các hàm đầu vào-đầu ra được thảo luận trong chương trước, chẳng hạn như, terpri và định dạng đang hoạt động để ghi vào tệp chúng tôi đã tạo ở đây.
Khi bạn thực thi mã, nó không trả về bất cứ thứ gì; tuy nhiên, dữ liệu của chúng tôi được ghi vào tệp. Các:direction :output từ khóa cho phép chúng tôi làm điều này.
Tuy nhiên, chúng tôi có thể đọc từ tệp này bằng cách sử dụng read-line chức năng.
Ví dụ 2
Tạo một tệp mã nguồn mới có tên main.lisp và nhập mã sau vào đó.
(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)
)
)
Khi bạn thực thi mã, nó trả về kết quả sau:
Welcome to Tutorials Point!
This is a tutorials database
Submit your Tutorials, White Papers and Articles into our Tutorials Directory.
Đóng tệp
Các close hàm đóng một luồng.