2011-06-09 24 views
6

32-bit'lik bir sıra içeren bir ikili dosyam var. Onları bir listeye (veya muhtemelen kullanacağım Data.Array) okumaya nasıl başlarım?İkili bir dosyadan ingilizlerin sıralamasını okuma

Bu belgede bulabildiğim tek şey bu hGetBuf işlevidir ve kullanımı hakkında nasıl netleşeceği açık değildir (bir arabelleğe Ptr ister misiniz?). http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.3.1.0/System-IO.html#v:hGetBuf

Elbette basit bir yaklaşım olmalı, ancak bulamıyorum!

cevap

4

Dosya sadece 32 bit ints ise, o zaman @ TomMD'nin uyarısı. Böyle bir şey işi yapmalı.

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" 
+0

Teşekkürler Anthony! BL.fromChunks'in amacı nedir? (: []) <$>. BS.readFile burada mı? Neden sadece "BL.readFile" değil? – masonk

+0

@masonk Muhtemelen gereksizdir. Niyetimin bu şekilde yazıldığından emin değilim. – Anthony

4

Bunu binary paketi ile kolayca yapabilirsiniz. Dosya okuma belgelerini here bulabilirsiniz.

Zaten 32 bit tam sayıların bir listesini serileştirmenin bir yolunu içerir, bu nedenle decodeFile işlevini çağırmanız yeterlidir. Sen netlik için bunu bir daktilo-sürümüne sahip isteyebilirsiniz:

decodeIntsFile :: FilePath -> IO [Int32] 
decodeIntsFile = decodeFile 

Sonra, bir dizi olarak tamsayılar listenizi istediğiniz uygun dizi dönüşüm kullanırsanız, bu tür listArray olarak.

+5

@oadams Be warned! [Int32] 'için' Binary' örneği belirli bir format bekler (dosya, listenin uzunluğunu belirten bir alanla başlar). Dosyanız bu formatta değilse (belki de EOF'ye kadar sadece 32 bitlik değerler mi?), Daha sonra öntanımlı liste örneğini değil, 'binary'yi kullanabilirsiniz. –

İlgili konular