在我当前的工作目录中有一个名为test.txt
的文件,其中包含"Test\n"
。
使用System.IO.readFile
,GHCI返回内容:
Prelude System.IO> readFile "test.txt"
"Test\n"
但不是以下情况,我认为这应该是平等的:
Prelude System.IO> withFile "test.txt" ReadMode hGetContents
""
为什么不是这样?如何在withFile
IO
操作中获取整个文件内容?
答案 0 :(得分:3)
TL; DR:懒惰的IO是邪恶的。
当hGetContents
返回文件内容的IO-lazy列表时会发生什么。这意味着只有在实际访问所述列表时才会读取文件句柄。然后控件转到withFile
,关闭文件句柄。最后,打印结果,并且需要列表:现在只在句柄上执行读取。唉,已经太晚了。
作为一种丑陋的手动“冲洗”这种懒惰,你可以试试,例如。
hGetCont handle = do
c <- hGetContents handle
length c `seq` return c
以上强制计算列表的长度,因此强制读取整个文件。下面的里德巴顿提出了更多美丽的选择,避免使用可怕的邪恶懒惰的IO。