簡體   English   中英

如何通過流式ByteString跟蹤進度?

[英]How to track progress through a streaming ByteString?

我正在使用streaming-utils streaming-utils來傳輸HTTP響應主體。 我想跟蹤類似於bytestring-progress如何允許惰性ByteString進度 我懷疑像toChunks這樣的東西是必要的,然后減少一些累積的字節讀取並返回未經修改的原始流。 但我無法弄明白, 流式文檔非常無用,大多數都是對替代庫的宏大比較。

到目前為止,這是我最努力的代碼。 它還沒有包括計數,只是嘗試在流過(並且不編譯)時打印塊的大小。

download :: ByteString -> FilePath -> IO ()
download i file = do
  req <- parseRequest . C.unpack $ i
  m <- newHttpClientManager
  runResourceT $ do
    resp <- http req m
    lift . traceIO $ "downloading " <> file
    let body = SBS.fromChunks $ mapsM step $ SBS.toChunks $ responseBody resp
    SBS.writeFile file body

step bs = do
  traceIO $ "got " <> show (C.length bs) <> " bytes"
  return bs

我們想要的是以兩種方式遍歷Stream (Of ByteString) IO ()

  • 一個累積ByteString的傳入長度並將更新打印到控制台。
  • 將流寫入文件的人。

我們可以在copy功能的幫助下完成, copy功能具有以下類型:

 copy :: Monad m => Stream (Of a) mr -> Stream (Of a) (Stream (Of a) m) r 

copy獲取流並將其復制到兩個不同的monadic層中,其中原始流的每個元素由新的解離流的兩個層發出。

(請注意,我們正在更改基本monad,而不是functor。將functor更改為另一個Stream做法是在單個流中划分組 ,我們對此不感興趣。)

以下函數獲取流,復制它,使用S.scan累積傳入字符串的長度, 打印它們 ,並返回另一個仍可使用的流,例如將其寫入文件:

{-# LANGUAGE OverloadedStrings #-}
import Streaming
import qualified Streaming.Prelude as S
import qualified Data.ByteString as B

track :: Stream (Of B.ByteString) IO r -> Stream (Of B.ByteString) IO r
track stream =
      S.mapM_ (liftIO . print) -- brings us back to the base monad, here another stream
    . S.scan (\s b -> s + B.length b) (0::Int) id
    $ S.copy stream

這將打印ByteString以及累積的長度:

main :: IO ()
main = S.mapM_ B.putStr . track $ S.each ["aa","bb","c"]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM