E / S lenta e haskell e arquivos de fechamento
Eu escrevi um pequeno programa Haskell para imprimir as somas de verificação MD5 de todos os arquivos no diretório atual (pesquisado recursivamente). Basicamente, uma versão Haskell domd5deep
. Tudo está bem e elegante, exceto se o diretório atual tiver um número muito grande de arquivos; nesse caso, eu recebo um erro como:
<program>: <currentFile>: openBinaryFile: resource exhausted (Too many open files)
Parece que a preguiça de Haskell está fazendo com que ele não feche os arquivos, mesmo após a conclusão da linha de saída correspondente.
O código relevante está abaixo. A função de interesse égetList
.
import qualified Data.ByteString.Lazy as BS
main :: IO ()
main = putStr . unlines =<< getList "."
getList :: FilePath -> IO [String]
getList p =
let getFileLine path = liftM (\c -> (hex $ hash $ BS.unpack c) ++ " " ++ path) (BS.readFile path)
in mapM getFileLine =<< getRecursiveContents p
hex :: [Word8] -> String
hex = concatMap (\x -> printf "%0.2x" (toInteger x))
getRecursiveContents :: FilePath -> IO [FilePath]
-- ^ Just gets the paths to all the files in the given directory.
Há alguma idéia de como eu poderia resolver esse problema?
Todo o programa está disponível aqui:http://haskell.pastebin.com/PAZm0Dcb
Editar: Como tenho muitos arquivos que não cabem na RAM, não procuro uma solução que leia todo o arquivo na memória de uma só vez.