मान लीजिए कि मुझे एक बाइनरी फ़ाइल को पार्स करने की आवश्यकता है, जो तीन 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
एक त्रुटि लौटना चाहिए। पर कैसे? एक तर्क के रूप में वास्तविक लंबाई पारित करने का एकमात्र तरीका है? क्या यह ऐसा करने के लिए iteratee-ish तरीका है? मेरे लिए बहुत वृद्धि नहीं है :)
एक तर्क के रूप वास्तविक फ़ाइल लंबाई गुजर जब शुरू में एक इटरेटर पैदा करने के साथ कार्यक्रम क्या है? फ़ाइल लंबाई को तर्क के रूप में लेने के लिए शायद अपने फ़ंक्शन 'iterMagics' को बदलें। यदि आप स्मार्ट प्रोग्राम करते हैं, तो आपके कोड को केवल एक बार लंबाई पारित करने की आवश्यकता होती है। – fuz