假設我需要解析一個二進制文件,它以三個4字節的幻數開始。其中兩個是固定的字符串。另一個是文件的長度。Iteratee I/O:事先需要知道文件大小
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Attoparsec
import Data.Attoparsec.Enumerator
import Data.Enumerator hiding (foldl, foldl', map, head)
import Data.Enumerator.Binary hiding (map)
import qualified Data.ByteString as S
import System
main = do
f:_ <- getArgs
eitherStat <- run (enumFile f $$ iterMagics)
case eitherStat of
Left _err -> putStrLn $ "Not a beam file: " ++ f
Right _ -> return()
iterMagics :: Monad m => Iteratee S.ByteString m()
iterMagics = iterParser parseMagics
parseMagics :: Parser()
parseMagics = do
_ <- string "FOR1"
len <- big_endians 4 -- need to compare with actual file length
_ <- string "BEAM"
return()
big_endians :: Int -> Parser Int
big_endians n = do
ws <- count n anyWord8
return $ foldl1 (\a b -> a * 256 + b) $ map fromIntegral ws
如果規定長度不符合實際的長度,最好iterMagics
應該返回一個錯誤。但是如何?是否只有將實際長度作爲參數傳遞的唯一方法?這是迭代式的方式嗎?對我來說不是非常增量:)
最初生成迭代器時,將實際文件長度作爲參數傳遞的程序是什麼?也許改變你的函數'iterMagics'把文件長度作爲參數。如果你聰明地編程,你的代碼只需要傳遞一次。 – fuz