我有以下代碼用于加載檔案內容并使用 aeson 將其決議為物件:
loadFromFile filename = do
fileHandle <- openFile ( dataDir "/" filename ) ReadMode
contents <- B.hGetContents fileHandle
let result = fromMaybe initial $! JSON.decode contents in do
hClose fileHandle
return $! result
此代碼的問題在于它會導致以下錯誤:
filename.json: hGetBufSome: illegal operation (handle is closed)
filename.json: hGetBufSome: illegal operation (handle is closed)
我不太明白為什么它認為檔案句柄已關閉。畢竟,我在關閉手柄之前正在閱讀它。還是懶惰評估影響執行順序?我嘗試添加相應的$!運算子以使其更快評估,但無濟于事。如果我洗掉hClose fileHandle行,那么我開始收到以下型別的零星錯誤:
filename.json: openFile: resource busy (file is locked)
如果有人知道如何修復這個 catch22,我將不勝感激。謝謝!
uj5u.com熱心網友回復:
不是在關閉句柄后強制結果,您應該在關閉句柄之前強制結果,這是您可以使用的方法BangPatterns:
loadFromFile filename = do
fileHandle <- openFile ( dataDir "/" filename ) ReadMode
contents <- B.hGetContents fileHandle
let !result = fromMaybe initial $! JSON.decode contents
hClose fileHandle
return result
在這種情況下,不需要 deepseq,因為(我相信)該decode函式將在決定是否回傳之前處理整個輸入Nothingor Just ...,因此僅強制一級就足夠了。
而且,如果可能,最好完全避免使用句柄:
loadFromFile filename = do
contents <- B.readFile ( dataDir "/" filename )
return $! fromMaybe initial $! JSON.decode contents
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316822.html
上一篇:Haskell-給定串列,將其分解為彼此相鄰的相同專案的串列:[1,1,2,4,5,5]?[[1,1],[2],[4],[5,5]]]
