我的程序从网络套接字读取一行并将其写入光盘。由于行可能很长,并且字符串有可怕的性能,所以我开始使用懒惰字节字符串。目前看来,哈斯克尔将晃过hClose
光盘上的文件句柄实际上不冲洗整个字节串到光盘上,这样做:强制对惰性IO进行评估
- 打开文件进行写入
- 写字节字符串
hPut
- 关闭文件到文件
- 阅读
打开文件通常会导致openFile: resource busy (file is locked)
。
是否可以强制评估并等待整个字节串关闭文件之前写的,所以我可以肯定的是,文件是操作后实际关闭?
我的程序从网络套接字读取一行并将其写入光盘。由于行可能很长,并且字符串有可怕的性能,所以我开始使用懒惰字节字符串。目前看来,哈斯克尔将晃过hClose
光盘上的文件句柄实际上不冲洗整个字节串到光盘上,这样做:强制对惰性IO进行评估
hPut
打开文件通常会导致openFile: resource busy (file is locked)
。
是否可以强制评估并等待整个字节串关闭文件之前写的,所以我可以肯定的是,文件是操作后实际关闭?
由于唯一的其他答案是“使用别的东西”品种,我张贴我自己的解决方案。在hClose
之后使用此函数将挂起该线程,直到懒惰写入完成。
waitForLazyIO location = do
t <- liftIO $ try $ openFile location AppendMode
handle t
where
handle (Right v) = hClose v
handle (Left e)
-- Add some sleep if you expect the write operation to be slow.
| isAlreadyInUseError e = waitForLazyIO location
| otherwise = throwError $ show e
这可能会起作用,但坦率地说这是一种黑客攻击,并非真正达到haskell软件的通常标准。懒惰的IO路径充满了陷阱,因为这个概念被深深地打破了。目前,常量内存IO操作的唯一可行选择是左侧列举器,其中[conduit](http://hackage.haskell.org/package/conduit)是一个受欢迎的成员。 – 2012-04-13 15:13:56
尝试使用严格的字节字符串而不是惰性I/O和惰性字节字符串的严格I/O。
如果结果太差,请尝试使用conduit或类似的软件包。
你有没有看['hFlush'(http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-IO.html#v:hFlush)? – huon 2012-04-01 07:03:45
法拉盛没有帮助,就像'hClose'一样,GHC不经过等待就经过它。 – 2012-04-01 16:41:51