我要做的是使用takeWhile将字节串分割为某个字符。
import qualified Data.ByteString.Internal as BS (c2w, w2c)
import Pipes
import Pipes.ByteString as PB
import Pipes.GZip
import Pipes.Prelude as PP
import System.IO
newline = BS.c2w '\n'
splitter = PB.takeWhile (\myWord -> myWord /= newline)
myPipe fileHandle = PP.toListM $ decompress fileProducer >-> splitter
where
fileProducer = PB.fromHandle fileHandle
run = do
dat <- withFile "somefile.blob" ReadMode myPipe
pure dat
这让我获得了第一线,但我真正想要的是一次有效地将每个块产生到一个换行符。我该怎么做?
答案 0 :(得分:3)
@Michael回答很好。我只想说明一些 正在进行的使用模式。
(。{3}}提供<.lhs)
首先进口一些:
{-# LANGUAGE OverloadedStrings, NoMonomorphismRestriction #-}
import Pipes
import qualified Pipes.Prelude as PP
import qualified Pipes.Group as PG
import qualified Pipes.ByteString as PB
import qualified Pipes.GZip as GZip
import qualified Data.ByteString as BS
import Lens.Family (view, over)
import Control.Monad
import System.IO
如果查看Pipes.ByteString和Pipes.GZip中的函数 你会发现它们都属于以下类型模式:
每个类别中的功能示例:
PB.words
PG.concats
PB.lines
,PB.chunksOf
,PB.splits
,... GZip.compress
,GZip.decompress
以下是如何使用PB.words
将输入流拆分为单词:
prod = yield "this is\na test\nof the pipes\nprocessing\nsystem"
t1 = runEffect $ (PG.concats . PB.words) prod >-> PP.print
使用类型3的功能 - 例如PB.lines
,只需使用view
即可
Lens'
获取类型1的函数,然后使用PG.concats
撰写:
t2a = runEffect $ (PG.concats . view PB.lines) prod >-> PP.print
t2b h = (PG.concats . view PB.lines) (PB.fromHandle h) >-> PP.print
run2 = withFile "input" ReadMode (runEffect . t2b)
对于制片人 - &gt;生产者功能,只需使用普通功能应用程序:
t3 h = GZip.decompress (PB.fromHandle h) >-> PP.print
run3 = withFile "input.gz" ReadMode (runEffect . t3)
t4 h = GZip.decompress (PB.fromHandle h) >-> PP.map BS.length >-> PP.print
run4 = withFile "big.gz" ReadMode (runEffect . t4)
首先解压缩然后按行分割,我们嵌套函数 应用程序:
t5 h = (PG.concats . view PB.lines) ( GZip.decompress (PB.fromHandle h) )
>-> PP.map BS.length >-> PP.print
run5 = withFile "input.gz" ReadMode (runEffect . t5)
答案 1 :(得分:2)
ClientConnection
和pipes-bytestring
,以便反复打破pipes-group
会产生Producer ByteString m r
。 FreeT (Producer ByteString m) m r
在这里可以理解为FreeT
,因此结果可以被认为是'一连串的bytestring-producer段返回r'。这样,如果其中一个段长度为10千兆字节,we still have streaming rather than a 10 gigabyte strict bytestring。
在我看来你想要在换行符上打破bytestring生成器,但是我不知道你是否想要保留换行符。如果你将它们抛弃,这与将bytestring生成器与A_Succession_Of
分开,然后将每个从属生成器连接成一个严格的字节串 - 单独的行相同。我在下面写了view PB.lines
。这很简单,但只使用accumLines
将花哨的Lens.view
镜头变成常规功能。 (许多操作在PB.lines
中写成镜头,因为它们可以重复用于其他目的,尤其是解析pipes-bytestring
恩惠的生产者。)
pipes
理想情况下,您不会在每个换行符处写一个新的字节串。是否必须取决于你将如何处理这些线。