Reading multiple files fails

Henk-Jan.van.Tuyl Henk-Jan.van.Tuyl at hotpop.com
Fri Oct 10 02:33:48 EDT 2003


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


======================================================================
     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