简体   繁体   English

我尝试进行惰性I / O,但是整个文件都被消耗了

[英]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 . 如果您正在寻找一种真正有效的流媒体解决方案,那么我将研究pipesconduit而不是unsafeInterLeaveIO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM