[英]I try for lazy I/O, but entire file is consumed
I am a Haskell newbie. 我是Haskell新手。 I want to read only N characters of a text file into memory. 我只想将N个字符的文本文件读入内存。 So I wrote this code: 所以我写了这段代码:
main :: IO()
main = do
inh <- openFile "input.txt" ReadMode
transformedList <- Control.Monad.liftM (take 4) $ transformFileToList inh
putStrLn "transformedList became available"
putStrLn transformedList
hClose inh
transformFileToList :: Handle -> IO [Char]
transformFileToList h = transformFileToListAcc h []
transformFileToListAcc :: Handle -> [Char] -> IO [Char]
transformFileToListAcc h acc = do
readResult <- tryIOError (hGetChar h)
case readResult of
Left e -> if isEOFError e then return acc else ioError e
Right c -> do let acc' = acc ++ [transformChar c]
putStrLn "got char"
unsafeInterleaveIO $ transformFileToListAcc h acc'
My input file several lines, with the first one being "hello world", and when I run this program, I get this output: 我的输入文件多行,第一行是“ hello world”,运行此程序时,得到以下输出:
got char
transformedList became available
got char
["got char" a bunch of times]
hell
My expectation is that "got char" happens only 4 times. 我的期望是,“ char char”仅发生4次。 Instead, the entire file is read, one character at a time, and only THEN the first 4 characters are taken. 而是读取整个文件,一次读取一个字符,然后仅读取前四个字符。
What am I doing wrong? 我究竟做错了什么?
I acknowledge I don't understand how unsafeInterLeaveIO
works but I suspect the problem here is somehow related to it. 我承认我不了解unsafeInterLeaveIO
工作原理,但是我怀疑这里的问题与它有某种联系。 Maybe with this example you are trying to understand unsafeInterLeaveIO
, but if I were you I'd try to avoid its direct use. 也许在这个例子中,您试图了解unsafeInterLeaveIO
,但是如果我是我,我将避免直接使用它。 Here is how I'd do it in your particular case. 在您的特定情况下,这就是我的处理方法。
main :: IO ()
main = do
inh <- openFile "input.txt" ReadMode
charList <- replicateM 4 $ hGetChar inh
let transformedList = map transformChar charList
putStrLn "transformedList became available"
putStrLn transformedList
hClose inh
This should just read the first 4 characters of the file. 这应该只读取文件的前4个字符。
If you are looking for a truly effectful streaming solution, I'd look into pipes
or conduit
instead of unsafeInterLeaveIO
. 如果您正在寻找一种真正有效的流媒体解决方案,那么我将研究pipes
或conduit
而不是unsafeInterLeaveIO
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.