簡體   English   中英

使用Pipes在Haskell中讀取和寫入二進制數據

[英]Using Pipes to read and write binary data in Haskell

我試圖在常量內存中讀取和寫入很多整數。 我已經想出了如何將內存寫入內存,但還沒弄清楚如何將它們讀回來。

import Control.Lens (zoom)
import System.IO (IOMode(..), withFile)
import Pipes
import qualified Pipes.Prelude as P
import qualified Pipes.ByteString as PB    
import qualified Pipes.Parse as P
import qualified Pipes.Binary as P

intStream :: Monad m => Proxy x' x () Int m b
intStream = go (0 :: Int) where
   go i = yield i >> go (i + 1)

decoder :: Monad m => Int ->  P.Parser P.ByteString m [Int]
decoder n = zoom (P.decoded . P.splitAt n) P.drawAll

main :: IO ()
main = do
    withFile "ints" WriteMode $ \h -> do
         runEffect $ for intStream P.encode >-> P.take 10000 >-> PB.toHandle h
    withFile "ints" ReadMode $ \h -> do
         xs <- P.evalStateT (decoder 10000000) (PB.fromHandle h)
         print xs

我從Pipes.Binary的文檔中獲得了解碼器功能。 然而,它使用drawAll ,根據文檔 drawAll不是慣用的管道使用,並提供用於測試目的。

我的問題是如何修改decoder以便它不使用drawAll ,因此不會將xs所有值加載到內存中。 因此,不是打印P.map print列表,而是可以通過從文件讀取的解碼的intsP.map print

文檔說decoded是從字節流到解碼值流的鏡頭。 我們可以使用lens view從后者中取出后者:

decoder :: Monad m => Int -> Producer P.ByteString m a -> Producer Int m ()
decoder n p = void (view P.decoded p) >-> P.take n

main :: IO ()
main = do
    withFile "ints" WriteMode $ \h -> do
         runEffect $ for intStream P.encode >-> P.take 10000 >-> PB.toHandle h
    withFile "ints" ReadMode $ \h -> do
         runEffect $ decoder 10000 (PB.fromHandle h) >-> P.print

我沒有太多pipes經驗,我只是按照這里的類型。 該程序似乎按預期運行。

暫無
暫無

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

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