When is it better to explicitly close file handles?
haskell
Solution
It is better to explicitly close resources yourself, only when you have some low level resource constraint that you can actually enforce manually.
The cases to consider:
- resources aquired via lazy IO: must use the GC to free the resource
- strict IO: can close manually once input is read; or use a bracketing combinator (e.g. `finally` or `bracket`)
- incremental IO (conduits, iteratees): let the framework close it for you.
Problem
My first impression of `readFile` was of a tradeoff between its convenience and the possibility of it leaving file descriptors open longer than needed, with no way to close them. As an experiment I tried the following (highly practical) program, thinking it might choke by trying to maintain a thousand open file descriptors: ``` main = do mapM_ (\idx -> readIt) [1..1000] where readIt = do contents <- readFile "/etc/passwd" putChar $ head contents ``` But it actually does a pretty good job of reclaiming file descriptors; the count never gets above around 70: ``` open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 4 open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 5 open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 6 open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 7 ... open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 65 open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 66 close(3) = 0 close(4) = 0 close(5) = 0 ... close(54) = 0 close(55) = 0 close(56) = 0 open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 3 open("/etc/passwd", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 4 ``` How is this happening? Is it just that the values of `contents` are getting GC'd, and with them the no-longer-referenced file descriptors? Or is there some separate mechanism for managing file descriptor resources? Whatever the mechanism is, it seems to be working pretty well - how can you know when it's best to use `hClose` explicitly?