繁体   English   中英

使用io-streams将Data.Vector流传输到文件

[英]Streaming Data.Vector to File using io-streams

我正在尝试学习io流以将Data.Vector.Unboxed流化为磁盘上的文件; 但是,Int和ByteString之间类型不匹配。 我不太确定如何对齐将允许流式处理的输入和输出的类型。

import qualified Data.Vector.Unboxed as V
import System.IO.Streams.Core
import System.IO.Streams.File
import System.IO.Streams.Vector

new :: V.Vector Int
new = V.generate 1000000 (\i -> 1)

main :: IO ()
main = do
    withFileAsOutput "test.dat" $ \os -> writeVector new os

这是类型不匹配错误:

iostream.hs:12:66:
    Couldn't match type `Data.ByteString.Internal.ByteString'
                  with `Int'
    Expected type: OutputStream Int
      Actual type: OutputStream Data.ByteString.Internal.ByteString
    In the second argument of `writeVector', namely `os'
    In the expression: writeVector new os
    In the second argument of `($)', namely
      `\ os -> writeVector new os'

使用pipes非常容易做到这一点:

import Data.ByteString (hPut)
import qualified Data.Vector.Unboxed as V
import Pipes
import Pipes.Binary (encode)
import qualified System.IO as IO

new :: V.Vector Int
new = V.generate 1000000 (\i -> 1)

main = IO.withFile "test.dat" IO.WriteMode $ \handle ->
    runEffect $ for (V.mapM_ encode new) (lift . hPut handle)

通过System.IO.Streams.Combinators的相反映射 ,可以从ByteString的OutputStream获取Int的OutputStream。

您只需要提供一个转换功能,即可使用序列化类Binary完成此功能。

import qualified Data.Vector.Unboxed as V
import System.IO.Streams.Core
import System.IO.Streams.File
import System.IO.Streams.Vector

import System.IO.Streams.Combinators as SC

import Data.ByteString.Lazy as LBS
import Data.ByteString as BS

import Data.Binary (Binary, put, encode)
import Data.Binary.Put (runPut)

new :: V.Vector Int
new = V.generate 1000000 (\i -> 1)

toBS :: Binary a => a -> BS.ByteString
toBS = LBS.toStrict . encode          -- Data.Binary.encode = runPut . put

main :: IO ()
main = do
    withFileAsOutput "test.dat" $ \bsOStream -> do
      intOStream <- SC.contramap toBS bsOStream
      writeVector new intOStream
import qualified Data.Vector.Unboxed as V
import System.IO.Streams as S
import Data.ByteString.Lazy (toStrict)
import Data.Binary (encode)

new :: V.Vector Int
new = V.generate 100 (\i -> 1)

main :: IO ()
main =  S.withFileAsOutput "test.dat" (\outStream -> do
    inVectorStream <- S.fromVector new
    inByteStringStream <- S.map (toStrict . encode) inVectorStream
    S.connect inByteStringStream outStream)

不使用Systems.IO.Streams.Vector的替代方法,而是将整个向量序列化为ByteString OutputStream。

使用此版本,数据将更易于恢复。

{-# LANGUAGE PackageImports #-}

import qualified Data.Vector.Unboxed as V
import System.IO.Streams.Core
import System.IO.Streams.File
import System.IO.Streams.Vector

import Data.ByteString.Lazy as LBS
import Data.ByteString as BS

import Data.Binary (put, Binary)
import Data.Binary.Put (runPut)

import "vector-binary-instances" Data.Vector.Binary () -- binary instances

new :: V.Vector Int
new = V.generate 1000000 (\i -> 1)

toBS :: Binary a => a -> BS.ByteString
toBS = (LBS.toStrict . runPut . put)

main :: IO ()
main = do
    withFileAsOutput "test.dat" $ \bsOStream -> do
      write (Just $ toBS new) bsOStream

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM