我有以下函数:
safeWrite :: Text -> IO ()
safeWrite c = bracket (openTempFile "/tmp" "list.tmp")
((path, h) -> hClose h
>> copyFile path dataFile
>> removeFile path)
((_, h) -> TI.hPutStr h c)
我的印象是这是安全的,如果任何时候出现错误,就不会发生复制,并且原始文件仍然可以使用。然而,就在昨天,我最终得到了一个空文件,我不知道去哪里看它。该程序已经运行了一个多月,没有任何打嗝,这是我没有想到的一些角落情况。
该方法是否保证原子性,这意味着错误在其他地方,或者如果不是,为什么不呢?我应该怎么做才能保证原子性?
你对mkTemp
的定义是关于Haskell例外的原子的。如果存在异常,它将打印有关失败的消息(将文件保留在那里)。
- 它相对于Unix文件系统不是原子的 - 其他程序可以覆盖相同的文件
- 如果出现故障,它不会清理。
您可以做更多的事情来清理,方法是在出现异常时选择性地删除文件,或者仅使用提供的(原子)mkTemp
函数:
-
openTempFile
: http://hackage.haskell.org/packages/archive/base/4.3.1.0/doc/html/System-IO.html#g:22
或使用 POSIX 层:
- http://hackage.haskell.org/packages/archive/unix/latest/doc/html/System-Posix-Temp.html#Temp