簡體   English   中英

何時在流字節字符串上調用runResourceT?

[英]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.

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