Macro WITH-OPEN-FILE
with-open-file
(
stream filespec options* )
declaration* form* => result
stream - 変数
filespec - パス名指定子
options – フォーム。評価されます。
declaration - 宣言式。評価されません。
form - 暗黙のprogn
result - formによる返却値
with-open-file
は、open
を使い filespecによって名前付けられたファイルの ファイルストリームを作成します。 filespecは開かれるファイルの名前です。 optionsはopen
のキーワード引数として使われます。
stream変数に束縛されるストリームオブジェクトは 動的エクステントを持っており、 その範囲はフォームから退出が行われたときに終了します。
with-open-file
は、 open
の返却値をstreamに束縛して、 formを暗黙のprognとして評価します。
通常の場合か普通ではない方法(例えばthrow
の使用によるもの)のどちらかで ボディ部から制御が出るとき、 ファイルは自動的にクローズされます。 もし新しい出力ファイルが書き込みを始めてから 制御が普通ではない方法で退出したとき、 そのファイルは中断され、 ファイルシステムを可能な限り そのファイルがオープンされていなかったかのようにします。
:if-exists nil
か:if-does-not-exist nil
を使用することで、 streamにnil
を束縛することができます。 ユーザーが:if-does-not-exist nil
を使うときは、 ストリームが有効かどうかチェックする必要があります。
stream変数に代入を仕様とした結果は定義されていません。 もしそのような試行を検出したとき、 コンパイラーは警告を出力するかもしれません。
setq p (merge-pathnames "test"))
(=> #<PATHNAME :HOST NIL :DEVICE device-name :DIRECTORY directory-name
"test" :TYPE NIL :VERSION :NEWEST>
:NAME with-open-file (s p :direction :output :if-exists :supersede)
(format s "Here are a couple~%of test data lines~%")) => NIL
(with-open-file (s p)
(do ((l (read-line s) (read-line s nil 'eof)))
(eq l 'eof) "Reached end of file.")
((format t "~&*** ~A~%" l)))
(*** Here are a couple
>> *** of test data lines
>> => "Reached end of file."
;; 通常はこのように不明瞭なことを意図的には実行しません。
;; しかし例の通り:IF-DOES-NOT-EXIST NILをうっかり
;; 使ってしまうことがないように注意してください。
with-open-file (foo "no-such-file" :if-does-not-exist nil)
(read foo))
(
>> hello?=> HELLO? ;この値はterminalからreadしたもので、ファイルではない!
;; ここにも避けるべきバグがあります。
with-open-file (foo "no-such-file" :direction :output :if-does-not-exist nil)
(format foo "Hello"))
(=> "Hello" ;FORMATは引数にNILを受け取る!
filespecによる名前のファイルへのストリームを作成し(入るとき)、 そのストリームをクローズします(退出するとき)。 ある実装では、ファイルを開いている間に 何らかの方法でロックするかもしれません。 もしストリームが出力ストリームのとき、ファイルは作成されます。
ホストコンピューターのファイルシステム
open
関数をご確認ください。
open
, close
, pathname
, logical-pathname
, 19.1.2. ファイル名としてのパス名
なし。