我有一个包含32位整数序列的二进制文件。我该如何将它们读入列表(或Data.Array,我可能最终会使用它)?从二进制文件读取整数的顺序
我能在文档中找到的是这个hGetBuf函数,并且不清楚如何去使用它(需要一个Ptr到缓冲区?)。 http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.3.1.0/System-IO.html#v:hGetBuf
当然,必须有一个简单的方法,但我找不到它!
我有一个包含32位整数序列的二进制文件。我该如何将它们读入列表(或Data.Array,我可能最终会使用它)?从二进制文件读取整数的顺序
我能在文档中找到的是这个hGetBuf函数,并且不清楚如何去使用它(需要一个Ptr到缓冲区?)。 http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.3.1.0/System-IO.html#v:hGetBuf
当然,必须有一个简单的方法,但我找不到它!
如果该文件只是32位整数,那么请留意@ TomMD的警告。像这样的东西应该可以完成这项工作。
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"
您可以使用binary
软件包轻松完成此操作。你可以找到文件阅读文件here。
它已经包含一个反序列化32位整数列表的方法,所以你只需要调用decodeFile
函数。你可能想拥有它的类型化版本,为清楚:
decodeIntsFile :: FilePath -> IO [Int32]
decodeIntsFile = decodeFile
然后如果你希望你的整数列表作为一个数组,使用适当的阵列转换,如listArray
。
@oadams被警告! '[Int32]'的'Binary'实例需要一个特定的格式(即文件以指示列表长度的字段开头)。如果你的文件不是这种格式(也许它只是EOF之前的原始32位值),那么你仍然可以使用'binary',而不是预定义的列表实例。 – 2011-06-09 17:47:55
谢谢安东尼! 'BL.fromChunks有什么意义? (:[])<$>。 BS.readFile'在这里?为什么不只是'BL.readFile'? – masonk 2013-09-03 17:56:45
@masonk它可能是多余的。我不确定我的意图是以这种方式写作。 – Anthony 2013-09-06 21:40:52