Книга: Practical Common Lisp
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. 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
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-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*)
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
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