Jog*_*ger 6 haskell bytestring
使用以下代码,我想将 Data.Text 值序列化为 ByteString。不幸的是,我的文本前面添加了不必要的 NUL 字节和 EOT 字节:
GHCi, version 9.4.4: https://www.haskell.org/ghc/ :? for help
ghci> import qualified Data.Text as T
ghci> import Data.Binary
ghci> import Data.Binary.Put
ghci> let txt = T.pack "Text"
ghci> runPut $ put txt
"\NUL\NUL\NUL\NUL\NUL\NUL\NUL\EOTText"
ghci>
Run Code Online (Sandbox Code Playgroud)
问题:
PS:我真正的代码我把长度放在文本前面
foo :: Text -> ByteString
foo txt = runPut do
putWord32host $ T.length txt
put txt
Run Code Online (Sandbox Code Playgroud)
它实际上已经对二进制字符串的长度进行了编码。事实上,如果我们查看源代码,对于Text
的实例Binary
,我们会看到\xc2\xa0 [src]:
\n\nRun Code Online (Sandbox Code Playgroud)\ninstance Binary Text where\n put t = put (encodeUtf8 t)\n get = do\n bs <- get\n case decodeUtf8\' bs of\n P.Left exn -> P.fail (P.show exn)\n P.Right a -> P.return a
这并不奇怪,我们将其编码为 UTF-8,生成一个ByteString
,然后使用put
它。但长度是在我们本身的时候加上put
的ByteString
。事实上,BinaryString
实例Binary
看起来像\xc2\xa0 [src]:
\n\nRun Code Online (Sandbox Code Playgroud)\ninstance Binary B.ByteString where\n put bs = put (B.length bs)\n <> putByteString bs\n get = get >>= getByteString
因此put
,产生ByteString
的 写入encodeUtf8
八个字节来指定 的大小,因此这是字节ByteString
数,而不是(本身与)中的字符数Text
。
如果您想要相同的效果,但没有长度前缀,您可以使用:
\nimport Data.Text.Encoding\n\nrunPut (putByteString (encodeUtf8 txt))\n
Run Code Online (Sandbox Code Playgroud)\n因此,这省略了长度标头。
\n 归档时间: |
|
查看次数: |
67 次 |
最近记录: |