我正在尝试添加到我正在编写的程序中,这一功能可以将打印到控制台的所有内容添加到日志文件中.这可以通过广播流来完成.问题是程序可能还需要从叶子函数中突然退出,当我这样做时,日志文件不会被创建.这是我到目前为止:
(catch 'quit
(with-open-file (log-stream "log.txt"
:direction :output
:if-exists :supersede
:if-does-not-exist :create)
(let ((*standard-output*
(make-broadcast-stream *standard-output* log-stream)))
(format t "abc~%")
(throw 'quit nil))))
Run Code Online (Sandbox Code Playgroud)
当我运行上面的代码(SBCL 1.4.2,Windows 7)时,文件log.txt不会被创建.如果我替换(throw 'quit nil),也是如此(quit).但是,如果我完全删除该行并让程序通过从文件末尾掉落而退出,则会正确创建日志文件,这表明它是一个缓存问题.
这是正确的诊断吗?如果是这样,有没有办法告诉编译器不要缓存该文件,或者退出而不是编写缓存数据?
这是标准中描述的行为WITH-OPEN-FILE:
如果正在写入新的输出文件,并且控制异常,则文件将中止并尽可能保留文件系统,就好像文件从未打开过一样.
以下显式关闭文件:
(catch 'quit
(with-open-file (log-stream "/tmp/log.txt"
:direction :output
:if-exists :supersede
:if-does-not-exist :create)
(let ((*standard-output* (make-broadcast-stream *standard-output* log-stream)))
(unwind-protect (progn
(format t "abc~%")
(throw 'quit nil))
(finish-output)
(close log-stream :abort nil)))))
Run Code Online (Sandbox Code Playgroud)
该:abort nil值是默认值,为了答案,它在此处明确.