2012-03-31 131 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或類似的軟件包。