2017-11-01 7 views
1

私はDouble行列が行順リストとして続くヘッダーで構成されるバイナリファイルを書き込むConduitを構築しています。コードは次のとおりです。バイナリファイルライターは、余分なバイトを追加します

import Conduit ((.|), ConduitM, mapC, sinkFileBS, yield) 
import Control.Monad.Trans.Except (ExceptT) 
import Control.Monad.Trans.Resource (ResourceT) 
import Data.ByteString (ByteString) 
import Data.ByteString.Conversion (toByteString') 
import Data.Serialize.IEEE754 (putFloat64be) 
import Data.Serialize.Put (putListOf, runPut) 
import Data.Void (Void) 
import Numeric.LinearAlgebra.Data ((><), Matrix, toLists) 
import System.FilePath (FilePath) 

type FileWriter = ResourceT (ExceptT String IO) 

matrixSink :: FilePath -> ConduitM (Matrix Double) Void FileWriter() 
matrixSink path = byteBuilder .| sinkFileBS path where 
    byteBuilder = do 
    yield $ toByteString' "header" 
    mapC fromDoubleMatrix 

fromDoubleMatrix :: Matrix Double -> ByteString 
fromDoubleMatrix matrix = runPut $ 
    putListOf putFloat64be (concat toLists matrix) 

これはほとんど動作します。私がそれを使ってテストすれば

runExceptT . runConduitRes $ yield matrix .| matrixSink "test.dat" 
    where matrix = (2 >< 2) [1, 2, 3, 4] 

私は予想されるファイルを得ますが、ヘッダーと倍精度のリストの間に余分なバイトがあります。 show使用して表示する場合、余分なバイトは次のようになります。

"\NUL\NUL\NUL\NUL\NUL\NUL\NUL\t" 

任意のアイデアどのようにではない、このバイトを印刷するには?それとも、それが標準的な区切りか何か(私はそれを読者で無視できるように)ですか?

EDIT:fromDoubleMatrixputListOf構成で問題が発生しているようです。

+0

可能な重複/stackoverflow.com/questions/11380470/serializing-a-string-with-data-cereal-or-data-binary) – jorgen

答えて

1
putListOf :: Putter a -> Putter [a] 
putListOf pa = \l -> do 
    putWord64be (fromIntegral (length l)) 
    mapM_ pa l 

putListOfは、個々のリスト要素をエンコードする前にリストの長さをエンコードします。私はあなたがその長さを必要としないので、多分あなたは固定された2×2行列を扱っていると思うし、あなただけしたい:/:[Data.CerealまたはData.Binaryとの文字列をシリアル化](HTTPSの

fromDoubleMatrix :: Matrix Double -> ByteString 
fromDoubleMatrix matrix = runPut $ 
    mapM_ putFloat64be (concat toLists matrix) 
関連する問題