使用Haskell的zip-conduit从zip存档中的文件中读取行

时间:2013-11-21 17:01:28

标签: haskell zip conduit

正如标题所说,我希望能够使用zip-conduit从zip存档中的文件中读取行(我正在处理的zip文件非常大,所以我需要能够在恒定的记忆中做到这一点)。我理解了管道的基本概念,但从来没有在愤怒中使用它们,并且我对从何处开始感到困惑。我已经阅读了管道教程,但是我无法将其与我的问题相匹配。

zip-conduit文档说,可以通过以下内容从zip存档中获取:

import qualified Data.Conduit.Binary as CB
import Codec.Archive.Zip

withArchive archivePath $ do
    name:_ <- entryNames
    sourceEntry name $ CB.sinkFile name

我认为我需要做的是代替CB.sinkFile写一些东西。 Data.Conduit.Text有一个lines函数 - 是否可以通过某种方式将这些行从文件中删除?

我真的很感激一个简单的例子,比如使用putStrLn写出一个存档在zip文件中的简单文本文件的行。提前谢谢。

3 个答案:

答案 0 :(得分:6)

迈克尔的答案,但是zip-conduit

import           Control.Monad.IO.Class (liftIO)
import           Data.Conduit
import qualified Data.Conduit.List as CL
import qualified Data.Conduit.Text as CT
import           Codec.Archive.Zip

main :: IO ()
main = withArchive "input.zip" $ do
  n:_ <- entryNames
  sourceEntry n
     $ CT.decode CT.utf8
    =$ CT.lines
    =$ CL.mapM_ (\t -> liftIO $ putStrLn $ "Got a line: " ++ show t)

答案 1 :(得分:1)

这是一个简单的例子:

import           Control.Monad.IO.Class (liftIO)
import           Data.Conduit
import qualified Data.Conduit.Binary    as CB
import qualified Data.Conduit.List      as CL
import qualified Data.Conduit.Text      as CT

main :: IO ()
main = runResourceT
     $ CB.sourceFile "input.txt"
    $$ CT.decode CT.utf8
    =$ CT.lines
    =$ CL.mapM_ (\t -> liftIO $ putStrLn $ "Got a line: " ++ show t)

您也可以view and experiment on FP Haskell Center

答案 2 :(得分:1)

这是一个简单的例子 -

import Data.ByteString as B
import Data.Conduit
import qualified Data.Conduit.List as CL
import qualified Data.Conduit.Binary as CB
import Codec.Archive.Zip
import System.Environment

sink :: Monad m => Sink ByteString m [ByteString]
sink = CL.consume

main::IO()
main = do
    [archivePath] <- getArgs
    res <- withArchive archivePath $ do
        name:_ <- entryNames
        source <- getSource name
        runResourceT $ (source $$ sink)

    print res

您可以在接收器功能中处理数据(根据需要使用CL,CB功能),或者由于数据是懒惰地返回,您可以修改res中的数据。