在没有缓冲的情况下读取大文件中的大行

Cha*_*ham 6 haskell haskell-pipes

我想知道是否有一种简单的方法可以一次从文件中获取一行,而不是最终将整个文件加载到内存中.我想用attoparsec解析器在线上进行折叠.我尝试使用Data.Text.Lazy.IO,hGetLine这打击了我的记忆.我后来读到最终加载整个文件.

我使用也试过管道文本foldsview lines:

s <- Pipes.sum $ 
    folds (\i _ -> (i+1)) 0 id (view Text.lines (Text.fromHandle handle))
print s
Run Code Online (Sandbox Code Playgroud)

只计算行数,它似乎做了一些不稳定的东西"hGetChunk:无效的参数(无效的字节序列)",需要11分钟,wc -l需要1分钟.我听说管道文本可能有一些巨大的线条问题?(每行约1GB)

我对任何建议都很开放,除了新手readLine怎么样之外找不到多少搜索.

谢谢!

Mic*_*man 7

以下代码使用Conduit,并将:

  • UTF8解码标准输入
  • lineC只要有更多可用数据,就运行组合器
  • 对于每一行,只需yield输入值1并丢弃行内容,而不必立即将整行读入内存
  • 总结1s得出并打印出来

您可以将yield 1代码替换为将在各行上进行处理的代码.

#!/usr/bin/env stack
-- stack --resolver lts-8.4 --install-ghc runghc --package conduit-combinators
import Conduit

main :: IO ()
main = (runConduit
     $ stdinC
    .| decodeUtf8C
    .| peekForeverE (lineC (yield (1 :: Int)))
    .| sumC) >>= print
Run Code Online (Sandbox Code Playgroud)