关闭文件句柄会导致 Haskell 出现问题
Closing file handle causes troubles in Haskell
我有以下代码用于加载文件内容并使用 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,我将不胜感激。谢谢!
与其在关闭句柄后强制执行结果,不如在关闭句柄之前强制执行结果,以下是使用 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
函数会在决定是 return Nothing
还是 [=15= 之前处理整个输入], 所以只强制一级就够了。
而且,如果可能的话,最好完全避免句柄:
loadFromFile filename = do
contents <- B.readFile ( dataDir ++ "/" ++ filename )
return $! fromMaybe initial $! JSON.decode contents
我有以下代码用于加载文件内容并使用 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,我将不胜感激。谢谢!
与其在关闭句柄后强制执行结果,不如在关闭句柄之前强制执行结果,以下是使用 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
函数会在决定是 return Nothing
还是 [=15= 之前处理整个输入], 所以只强制一级就够了。
而且,如果可能的话,最好完全避免句柄:
loadFromFile filename = do
contents <- B.readFile ( dataDir ++ "/" ++ filename )
return $! fromMaybe initial $! JSON.decode contents