Книга: Practical Common Lisp
Closing Files
Closing Files
As anyone who has written code that deals with lots of files knows, it's important to close files when you're done with them, because file handles tend to be a scarce resource. If you open files and don't close them, you'll soon discover you can't open any more files.[155] It might seem straightforward enough to just be sure every OPEN
has a matching CLOSE
. For instance, you could always structure your file using code like this:
(let ((stream (open "/some/file/name.txt")))
;; do stuff with stream
(close stream))
However, this approach suffers from two problems. One is simply that it's error prone—if you forget the CLOSE
, the code will leak a file handle every time it runs. The other—and more significant—problem is that there's no guarantee you'll get to the CLOSE
. For instance, if the code prior to the CLOSE
contains a RETURN
or RETURN-FROM
, you could leave the LET
without closing the stream. Or, as you'll see in Chapter 19, if any of the code before the CLOSE
signals an error, control may jump out of the LET
to an error handler and never come back to close the stream.
Common Lisp provides a general solution to the problem of how to ensure that certain code always runs: the special operator UNWIND-PROTECT
, which I'll discuss in Chapter 20. However, because the pattern of opening a file, doing something with the resulting stream, and then closing the stream is so common, Common Lisp provides a macro, WITH-OPEN-FILE
, built on top of UNWIND-PROTECT
, to encapsulate this pattern. This is the basic form:
(with-open-file (stream-var open-argument*)
body-form*)
The forms in body-forms are evaluated with stream-var bound to a file stream opened by a call to OPEN
with open-arguments as its arguments. WITH-OPEN-FILE
then ensures the stream in stream-var is closed before the WITH-OPEN-FILE
form returns. Thus, you can write this to read a line from a file:
(with-open-file (stream "/some/file/name.txt")
(format t "~a~%" (read-line stream)))
To create a new file, you can write something like this:
(with-open-file (stream "/some/file/name.txt" :direction :output)
(format stream "Some text."))
You'll probably use WITH-OPEN-FILE
for 90-99 percent of the file I/O you do—the only time you need to use raw OPEN
and CLOSE
calls is if you need to open a file in a function and keep the stream around after the function returns. In that case, you must take care to eventually close the stream yourself, or you'll leak file descriptors and may eventually end up unable to open any more files.
- 14. Files and File I
- 4.3.3 Automatic Closing
- Для чего нужны папки Windows, Documents and Settings, Program Files и Temp?
- Можно ли указать использование по умолчанию вместо C:Program Files другого каталога для установки программ?
- Можно ли удалять из папки Program Files папки деинсталлированных программ?
- Use and Edit Files in the
- Абстрактный базовый класс FileSystemInfo
- Класс FileStream и байтовый ввод-вывод в файл
- Managing Files with the Shell
- Working with Compressed Files
- Access Variable Data Files in the
- Copying Files