[英]When to call runResourceT on streaming-bytestring?
我是Haskell的初學者,仍然在學習monad變壓器。
我正在嘗試使用streaming-bytestring庫讀取二進制文件,處理字節塊,並在處理每個塊時打印結果。 我相信這是流行的streaming
庫,它提供了惰性字節串的替代方案。 看來作者復制粘貼了惰性字節字符串文檔,並添加了一些任意示例。
這些示例提到了runResourceT
而沒有討論它是什么或如何使用它。 似乎應該在執行操作的任何流字節字符串函數上使用runResourceT
。 很好,但是如果我正在讀取處理塊並打印它們的無限流怎么辦? 每次我想處理塊時都應該調用runResourceT嗎?
我的代碼是這樣的:
import qualified Data.ByteString.Streaming as BSS
import System.TimeIt
main = timeIt $ processByteChunks $ BSS.drop 100 $ BSS.readFile "filename"
而且我不確定如何將processByteChunks
組織為遍歷二進制文件的遞歸函數。
如果只調用一次runResourceT
,它將在打印之前讀取無限文件,對嗎? 好像不好
main = timeIt $ runResourceT $ processByteChunks $ BSS.drop 100 $ BSS.readFile "filename"
完成使用后, ResourceT
monad會及時清理資源。 在這種情況下,它將確保在使用流時關閉由BSS.readFile
打開的文件句柄。 (除非流確實是無限的,否則我猜不會。)
在您的應用程序中,您只想調用一次,因為您不希望在讀取所有塊之前關閉文件。 不用擔心-它與輸出的時間或諸如此類無關。
這是一個具有遞歸processByteChunks
應該可以正常工作的示例。 它會延遲讀取並在延遲讀取塊時生成輸出:
import Control.Monad.IO.Class
import Control.Monad.Trans.Resource
import qualified Data.ByteString.Streaming as BSS
import qualified Data.ByteString as BS
import System.TimeIt
main :: IO ()
main = timeIt $ runResourceT $
processByteChunks $ BSS.drop 100 $ BSS.readFile "filename"
processByteChunks :: MonadIO m => BSS.ByteString m () -> m ()
processByteChunks = go 0 0
where go len nulls stream = do
m <- BSS.unconsChunk stream
case m of
Just (bs, stream') -> do
let len' = len + BS.length bs
nulls' = nulls + BS.length (BS.filter (==0) bs)
liftIO $ print $ "cumulative length=" ++ show len'
++ ", nulls=" ++ show nulls'
go len' nulls' stream'
Nothing -> return ()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.