Search code examples
haskellbytestring

Why does decodeFile throw "not enough bytes" error?


Why does decodeFile from Data.Binary throw the error *** Exception: demandInput: not enough bytes, when using decode and readFile from Data.ByteString.Lazy works as expected?

A minimal example

module Testing where

import Data.Binary
import qualified Data.Map.Strict as Map
import qualified Data.ByteString.Lazy as B

x :: Map.Map Char Int
x = Map.fromList $ zip ['a'..'d'] [1,2,3,4]

main :: IO (Map.Map Char Int)
main = do
  encodeFile "testing" (encode x)
  r <- decodeFile "testing"
  print $ r == x
  return r

main2 :: IO (Map.Map Char Int)
main2 = do
  B.writeFile "testing2" (encode x)
  r <- fmap decode $ B.readFile "testing2"
  print $ r == x
  return r

I found this potentially relevant question: Using Data.Binary.decodeFile, encountered error "demandInput: not enough bytes" but it does not really answer my question, which is why using decodeFile doesn't work but readFile does.

The output I get:

[1 of 1] Compiling Testing          ( testing.hs, interpreted )                                                                                                         
Ok, modules loaded: Testing.                                                                                                                                            
*Testing> main                                                                                                                                                          
*** Exception: demandInput: not enough bytes              

*Testing> main2                                                                                                                                                         
True                                                                                                                                                                    
fromList [('a',1),('b',2),('c',3),('d',4)]   

Solution

  • You have

    encodeFile "testing" (encode x)
    

    which means you're encoding x twice. Changing that to

    encodeFile "testing" x
    

    works as expected.