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