common-lisp - 退出而不丢失缓存的输出
问题描述
我正在尝试添加到我正在编写的程序中,该功能将打印到控制台的所有内容也添加到日志文件中。这可以通过广播流来完成。问题是程序可能还需要从叶函数中突然退出,当我这样做时,不会创建日志文件。这是我到目前为止所拥有的:
(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))))
当我运行上述代码(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)))))
该:abort nil
值是默认值,为了回答起见,此处明确说明。
推荐阅读
- html - 如何使用owl-date-module将纪元时间发送到Angular中的后端API?
- c# - How to avoid duplicates when inserting data using OleDB and Entity Framework?
- azure - Can you combine multiple CI builds prior to a CD pipeline being triggered in Azure DevOps?
- python - Pattern printing with arrays/tuples
- websphere - IBM CP Optimizer Community Edition
- javascript - 如何让元素重新出现?
- python - 特殊列表视图
- jestjs - 如何修复来自赛普拉斯测试的开玩笑/无独立预期?
- google-cloud-platform - 无效的参数被传递给 CloudDataFusionPipelineStateSensor 'failure_statuses'
- python - 在 NoElementException 之后继续循环