Common lisp 打开一个文件,如果该文件不存在,请执行其他操作
我想打开一个文件并读取其内容,如果该文件不存在,则执行其他操作 前者很容易实现:Common lisp 打开一个文件,如果该文件不存在,请执行其他操作,common-lisp,Common Lisp,我想打开一个文件并读取其内容,如果该文件不存在,则执行其他操作 前者很容易实现:打开文件 对于后者,我的第一个想法是使用handler-case捕捉错误,但是SBCL说它是SB-INT:SIMPLE-FILE-error,听起来像编译器内部符号,因此可能不可移植 可移植的方法是什么?如果要简单地创建: (with-open-file (foo "path/to/non-existing-file" :direction :output
打开文件
对于后者,我的第一个想法是使用handler-case
捕捉错误,但是SBCL说它是SB-INT:SIMPLE-FILE-error
,听起来像编译器内部符号,因此可能不可移植
可移植的方法是什么?如果要简单地创建:
(with-open-file (foo "path/to/non-existing-file" :direction :output
:if-does-not-exist :create)
;; do your duty on stream `foo`)
如果做了其他事情,让foo
绑定到nil
,并对这种情况给出说明:
(with-open-file (foo "no-such-file" :direction :output :if-does-not-exist nil)
(when foo
;; if file exists do what you intended
;; explicitely return a value with `(return ...)`
)
(unless foo
;; catch the case that `foo` is bound to nil
;; so these are instructions for the `file doesn't exist` case
))
如果文件不存在,nil
将绑定到foo。
然后可以测试
nil
,知道打开文件是否成功。使用:如果不存在nil
(请参阅):
使用不存在的路径名:
(test #P"/hopefully/path/does/not/exist")
=> :SOMETHING-ELSE
(test #P"/dev/urandom")
=> 123
使用现有路径名:
(test #P"/hopefully/path/does/not/exist")
=> :SOMETHING-ELSE
(test #P"/dev/urandom")
=> 123
正如Rainer所解释的,您还可以使用来检查文件是否存在,但在探测文件成功返回后但在实际打开之前,您可能会面临另一个进程删除该文件的风险
对于后者,我的第一个想法是使用handler case来捕获错误,但是SBCL说它是SB-INT:SIMPLE-FILE-error,听起来像编译器内部符号,因此可能是不可移植的
捕获特定于实现的错误时,可以尝试检查其类层次结构,以查找名称属于公共Lisp包的最近超类:
CL-USER> (inspect (find-class 'SB-INT:SIMPLE-FILE-ERROR))
The object is a STANDARD-OBJECT of type SB-PCL::CONDITION-CLASS.
0. %TYPE: (CLASS #<SB-PCL::CONDITION-CLASS SB-INT:SIMPLE-FILE-ERROR>)
...
5. DIRECT-SUPERCLASSES: (#<SB-PCL::CONDITION-CLASS COMMON-LISP:SIMPLE-CONDITION>
#<SB-PCL::CONDITION-CLASS COMMON-LISP:FILE-ERROR>)
6. DIRECT-SUBCLASSES: NIL
...
11. %CLASS-PRECEDENCE-LIST: (#<SB-PCL::CONDITION-CLASS SB-INT:SIMPLE-FILE-ERROR>
#<SB-PCL::CONDITION-CLASS COMMON-LISP:SIMPLE-CONDITION>
#<SB-PCL::CONDITION-CLASS COMMON-LISP:FILE-ERROR>
#<SB-PCL::CONDITION-CLASS COMMON-LISP:ERROR>
#<SB-PCL::CONDITION-CLASS COMMON-LISP:SERIOUS-CONDITION>
#<SB-PCL::CONDITION-CLASS COMMON-LISP:CONDITION>
#<SB-PCL::SLOT-CLASS SB-PCL::SLOT-OBJECT>
#<SB-PCL:SYSTEM-CLASS COMMON-LISP:T>)
...
这种情况下要处理的可移植错误类型是文件错误
(请参阅)。请参阅函数PROBE-file