I have a binary file containing a sequence of 32-bit ints. How do I go about reading them into an list (or Data.Array, which I'll probably end up using)?
All I can find in the documentation is this hGetBuf function, and it isn't clear how to go about use it (requires a Ptr to a buffer?). http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.3.1.0/System-IO.html#v:hGetBuf
Surely there must be a simple approach, but I can't find it!
If the file is just 32-bit ints, then heed @TomMD's warning. Something like this should do the job.
import Control.Applicative
import Control.Monad
import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString as BS
import Data.Int
import System.Posix
testPut = BL.writeFile "foo.bin" . runPut . mapM_ put $ nums
where nums :: [Int32]
nums = [5,6,7,8]
testGet :: IO [Int32]
testGet = do n <- fromInteger . toInteger . fileSize <$> getFileStatus "foo.bin"
let readInts = runGet (replicateM (n `div` 4) get)
readInts . BL.fromChunks . (:[]) <$> BS.readFile "foo.bin"
You can do this quite easily with the binary
package. You can find the file-reading documentation here.
It already includes a way to deserialize a list of 32-bit integers, so you would just need to do call the decodeFile
function. You may want to have a typed-version of it for clarity:
decodeIntsFile :: FilePath -> IO [Int32]
decodeIntsFile = decodeFile
Then if you want your list of integers as an array, use the appropriate array conversion, such as listArray
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With