Reading multiple files fails

Henk-Jan.van.Tuyl Henk-Jan.van.Tuyl at hotpop.com
Fri Oct 10 12:53:12 EDT 2003


L.S.,

As my e-mail program mangled the copy/pasted source code a bit, I resend it as an attachment.

Best regards,
Henk-Jan van Tuyl


On Fri, 10 Oct 2003 01:33:48 +0200, Henk-Jan.van.Tuyl <Henk-Jan.van.Tuyl at hotpop.com> wrote:

>
> L.S.,
>
> After reading through 60 or 61 files (about 220 kB), Hugs fails with the message:
>      (1426170 reductions, 2976893 cells, 68 garbage collections)
>      ERROR - Garbage collection fails to reclaim sufficient space
>
> This is done with the program below (ReadALot.lhs), which reads a series of files (these files are listed in dir.dat).
> The program reads the first and the last (non-empty) line of each file and writes them, together with the filename in
> the output file result.dat.
>
> The program works fine when compiled with GHC, it then reads 2946 files without a problem.
>
> More info.:
> System:       Windows 98
> Hugs version: Nov 2002
>
> Best regards,
> Henk-Jan van Tuyl-------------- next part --------------
{-
   ReadALot.lhs
   Read a lot of files

   2003-10-06

   History:
   031009  Added dummy parameter to "main"
-}

> import IO
> import Monad

> inputSet   :: String
> inputSet   = "dir.dat"

> outputFile :: String
> outputFile = "result.dat"

===============================================================================
main
===============================================================================

> main :: a -> IO ()
> main _ = 
>   do 
>     hInputSet   <- openFile inputSet   ReadMode
>     hOutputFile <- openFile outputFile WriteMode
>     fileNames   <- hGetContents hInputSet
>     allData     <- collectAllData $ lines fileNames 
>     hPutStrLn hOutputFile $ unlines allData   
>     hClose hInputSet
>     hClose hOutputFile


===============================================================================
collectAllData 
Read a list of file names and return file name, first line and last line
of each file in a list
===============================================================================

> collectAllData :: [String] ->      -- A list of filenames
>                   IO [String]      -- A list of results
> 
> collectAllData []                     = return []
> collectAllData (fileName : fileNames) = 
>   do
>     putStrLn $ "Reading: " ++ fileName
>     h <- openFile fileName ReadMode
> 
>     contents <- hGetContents h
>
>     dataFromFile <- 
>       return           $! 
>         parseFile      $ 
>         filter (/= "") $ 
>         lines contents 
>
>     let (firstLine, lastLine) = dataFromFile 

      To force reading of the file before closing, we add a "when" (from 
      the Monad library), with a boolean expression that uses lastLine
      and will always be true:

>     when (length lastLine >= 0) $
>       hClose h
>
>     rest  <- collectAllData fileNames
>
>     return $ fileName : firstLine : lastLine : "" : rest


===============================================================================
parseFile 
Returns the first and the last string of a list of strings, as a tuple
===============================================================================

> parseFile :: [String] -> (String, String)
> parseFile []       = ("", "")
> parseFile [x]      = (x,  "")
> parseFile (x : xs) = (x,  last xs)




More information about the Hugs-Bugs mailing list