2012-03-31 89 views
1

我的程序从网络套接字读取一行并将其写入光盘。由于行可能很长,并且字符串有可怕的性能,所以我开始使用懒惰字节字符串。目前看来,哈斯克尔将晃过hClose光盘上的文件句柄实际上不冲洗整个字节串到光盘上,这样做:强制对惰性IO进行评估

  • 打开文件进行写入
  • 写字节字符串hPut
  • 关闭文件到文件
  • 阅读

打开文件通常会导致openFile: resource busy (file is locked)

是否可以强制评估并等待整个字节串关闭文件之前写的,所以我可以肯定的是,文件是操作后实际关闭?

+0

你有没有看['hFlush'(http://hackage.haskell.org/packages/archive/base/latest/doc/html/System-IO.html#v:hFlush)? – huon 2012-04-01 07:03:45

+0

法拉盛没有帮助,就像'hClose'一样,GHC不经过等待就经过它。 – 2012-04-01 16:41:51

回答

0

由于唯一的其他答案是“使用别的东西”品种,我张贴我自己的解决方案。在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 
+0

这可能会起作用,但坦率地说这是一种黑客攻击,并非真正达到haskell软件的通常标准。懒惰的IO路径充满了陷阱,因为这个概念被深深地打破了。目前,常量内存IO操作的唯一可行选择是左侧列举器,其中[conduit](http://hackage.haskell.org/package/conduit)是一个受欢迎的成员。 – 2012-04-13 15:13:56

0

尝试使用严格的字节字符串而不是惰性I/O和惰性字节字符串的严格I/O。

如果结果太差,请尝试使用conduit或类似的软件包。