6

タイトルが示すように、zip コンジットを使用して、zip アーカイブ内にあるファイルから行を読み取れるようにしたいと考えています (私が扱っている zip ファイルは非常に大きいため、できるようにする必要がありますこれは定数メモリ内にあります)。私はコンジットの非常に基本的なアイデアを理解していますが、それらを怒って使用したことは一度もありません。コンジットのチュートリアルを読みましたが、それを自分の問題と一致させるのに苦労しています。

zip コンジットのドキュメントには、次のような方法で zip アーカイブから入手できると書かれています。

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

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

私がする必要があるのは、代わりに何かを書くことだと思いますCB.sinkFileData.Conduit.Textにはlines関数があります — これを何らかの方法で使用して、ファイルから行を取り出すことができますか?

putStrLnたとえば、 zip ファイル内にアーカイブされた単純なテキスト ファイルの行を書き出すために使用するなど、単純な例を示していただければ幸いです。前もって感謝します。

4

3 に答える 3

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)
于 2013-11-22T20:03:26.470 に答える
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 でデータを変更できます。

于 2013-11-21T19:12:52.523 に答える