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