2012-10-01 17 views
5

複数のファイルを定数メモリで1つのByteStringとして読み込むにはどうすればよいですか? Haskellでn個のファイルを遅延IO操作として遅延読み込めますか?

readFiles :: [FilePath] -> IO ByteString 

私は現在、次の実装を持っていますが、私は、メモリ内のファイルのn-1で終了します私がプロファイリングから見たものからだけでなく、私の理解。

readFiles = foldl1 joinIOStrings . map ByteString.readFile 
    where joinIOStrings ml mr = do 
           l <- ml 
           r <- mr 
           return $ l `ByteString.append` r 

は、私がここに欠陥が私が私が私が必要だと思うことは、それらを適用せずにfoldl1 joinIOStringsを交換する方法であるので、それらをリラップその後、IOアクションを適用していますということであることを理解しています。

答えて

7

複数のファイルを定数メモリで1つのByteStringとして読み込むにはどうすればよいですか?

メモリを一定にするには、Data.ByteString.Lazyが必要です。厳密なByteStringは遅れて読み取ることができず、O(sum of filesizes)のメモリが必要です。 mapM L.readFileは、ファイルを開くが、唯一のそれぞれの内容を読みます

import qualified Data.ByteString.Lazy as L 

readFiles :: [FilePath] -> IO L.ByteString 
readFiles = fmap L.concat . mapM L.readFile 

ファイルのではない、あまりにも多数、単にそれらのすべてを読み取るための

D.B.L.readFileを遅延読み込み)し、結果を連結することは良いですが、ファイルが要求されたとき。

ファイルの数が多い場合、1つのプロセスでOSが許可するオープンファイルハンドルの制限が使い尽くされる可能性があるため、さらに複雑なものが必要です。その内容が必要な場合、以前のファイルが既に閉じることができます読んだときに、各ファイルにのみ、開かれますように、あなたは

import System.IO.Unsafe (unsafeInterleaveIO) 

mapM_lazy :: [IO a] -> IO [a] 
mapM_lazy [] = return [] 
mapM_lazy (x:xs) = do 
       r <- x 
       rs <- unsafeInterleaveIO (mapM_lazy xs) 
       return (r:rs) 

mapMのあなた自身の怠惰なバージョンをでっち上げることができます。ハンドルを閉じる時間が保証されていないため、まだリソースの限界に達している可能性はわずかです。

または、好きなiteratee,enumeratorconduitなど、問題を系統的に解決するパッケージを使用できます。それらのそれぞれは、他の点に関して長所と短所があり、正しくコーディングされていれば、誤ってリソース制限に突入する可能性がなくなります。

+0

ありがとうございました。私はすでにData.ByteString.Lazyを使用していたことを述べておきます。これは、開いたハンドルごとに少しずつ増加するメモリ使用量でうまく機能しました。また、追加のパッケージを指摘してくれてありがとう、私はちょうどハスケルを学び始めて、まだそれらを渡って来ていない。 –

1

遅延バイト文字列(Data.ByteString.Lazy)を使用しているとします。そこにこれを行うには、おそらく他の方法がありますが、一つの選択肢は、単に使用することですconcat :: [ByteString] -> ByteString

import Control.Monad 
import Data.ByteString.Lazy (ByteString) 
import qualified Data.ByteString.Lazy as ByteString 

readFiles :: [FilePath] -> IO ByteString 
readFiles = fmap ByteString.concat . mapM ByteString.readFile 

(注:私は、コードをテストする時間を持っていますが、ドキュメントを読むことは、これは動作するはずと言っていません)

関連する問題