用户损坏,Data.Binary或破损安装损坏?

Tob*_*ius 3 serialization haskell

我正在尝试使用Data.Binary来序列化Map,但是我收到了一个错误:没有足够的字节.然后我试着用一个整数列表做一个更简单的例子,在这里,这也不起作用.什么可能是错的?我的代码中是否有错误,我误解了或者我的安装有问题,在这种情况下我该如何解决?

以下是我的测试代码......

import Data.Binary

worldfile = "binarysimple.world"
main = do
  ser <- decodeFileOrFail worldfile
  case ser of
       Right w -> showWorld $ show (w :: [Int]) 
       Left (_,s) -> putStrLn ("the error:"++s) >> newworld

newworld = do
  let world = [1,2,3] :: [Int]
  showWorld $ show world 
  encodeFile worldfile $ encode world

showWorld = putStrLn
Run Code Online (Sandbox Code Playgroud)

...运行时的输出:

ghci binarysimple.hs
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( binarysimple.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
Loading package array-0.4.0.1 ... linking ... done.
Loading package deepseq-1.3.0.1 ... linking ... done.
Loading package containers-0.5.0.0 ... linking ... done.
Loading package bytestring-0.10.0.2 ... linking ... done.
Loading package binary-0.7.1.0 ... linking ... done.
the error:demandInput: not enough bytes
[1,2,3]
*Main> newworld
[1,2,3]
*Main> main
the error:demandInput: not enough bytes
[1,2,3]
*Main> newworld
[1,2,3]
*Main>
Leaving GHCi.
$ ls -l binarysimple.world
-rw-r--r--  1 btobias  staff  40  8 Sep 21:15 binarysimple.world
Run Code Online (Sandbox Code Playgroud)

我不知道确切的格式,但这可能是合理的输出:

$ hexdump -C binarysimple.world
00000000  00 00 00 00 00 00 00 20  00 00 00 00 00 00 00 03  |....... ........|
00000010  00 00 00 00 00 00 00 01  00 00 00 00 00 00 00 02  |................|
00000020  00 00 00 00 00 00 00 03                           |........|
00000028
Run Code Online (Sandbox Code Playgroud)

Tho*_*son 8

问题

让我们回顾一下您的想法以及您在做什么.

您认为您正在使用binary编码Ints 列表并将该字节串写入文件.然后,您从文件中读取并解码Ints 列表以使其失败.

您实际在做的是将Ints 列表编码为字节串,然后将该bytestring编码为bytestring(因此,将额外的长度字段添加到字节之前)并将该bytestring写入磁盘.您的解码失败,因为您有磁盘encode(encode(list))而不是encode(list).

解决方案

只需更改行读数:

encodeFile worldfile $ encode world
Run Code Online (Sandbox Code Playgroud)

encodeFile worldfile world
Run Code Online (Sandbox Code Playgroud)

阅读Hexdump

00000000  00 00 00 00 00 00 00 20  00 00 00 00 00 00 00 03  |....... ........|
00000010  00 00 00 00 00 00 00 01  00 00 00 00 00 00 00 02  |................|
00000020  00 00 00 00 00 00 00 03
Run Code Online (Sandbox Code Playgroud)

所以上面的hexdump可以读成一系列64位整数:0x20,3,1,2,3.第一个值,十进制32,是编码的一部分,Bytestring表示剩余字节串的长度(8字节*4总).第二个值3是列表编码的一部分 - 它表示列表的长度.最终值是列表的各个元素.

最后,你不需要一些随机的在线人员向你解释格式,你可以从binary包中的实例中读取格式(一旦熟悉Haskell).