|
nr:
> > Sure, you can replace the openFile/hGetContents pair by readFile, but the > > real problem is the presence of the hClose. Removing that will solve your > > problem (but note that you now have no control over when the file is > > actually closed). > > Can I just leave it hanging and rely on the garbage collector to close > it in the fullness of time? Yeah, once your program has demanded the entire file, it'll close the Handle. > Because of laziness, I believe there's no point in my writing the > following: > > > load fn = do handle <- IO.openFile fn IO.ReadMode > > contents <- IO.hGetContents handle > > let xml = XP.xmlParse fn contents > > IO.hClose handle > > return xml > > Is that correct? Yep. Its not neccessary in the usual programming cases to explicitly close the handle. IF you start really hammering the filesystem do you start to care about ensuring files are closed (so you don't hang on to too many FDs). Or if you start mutating files on disk. For these situations there are strict readFiles, or Data.ByteString.readFile -- Don _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
[ moving to haskell-café... ]
Norman Ramsey wrote: > > There seems to be a misunderstanding here: readFile in > itself is not the > > solution. readFile is defined thus: > > > > readFile name = openFile name ReadMode >>= hGetContents > > > and the original code was this: > > > > load fn = do handle <- IO.openFile fn IO.ReadMode > > contents <- IO.hGetContents handle > > IO.hClose handle > > return $ XP.xmlParse fn contents > > > Sure, you can replace the openFile/hGetContents pair by > readFile, but the > > real problem is the presence of the hClose. Removing that > will solve your > > problem (but note that you now have no control over when > the file is > > actually closed). > > Can I just leave it hanging and rely on the garbage collector to > close it in the fullness of time? Yes. The problem I was alluding to arises when you have many lazilly-closed files, and you run into the system's open file limit because the runtime doesn't close them eagerly enough. To be sure of closing the file at the right time, you need to force the entire file to be read (e.g. by forcing the result of the parse), then close the handle. > Because of laziness, I believe there's no point in my writing the > following: > > > load fn = do handle <- IO.openFile fn IO.ReadMode > > contents <- IO.hGetContents handle > > let xml = XP.xmlParse fn contents > > IO.hClose handle > > return xml > > Is that correct? Yes. Cheers, Simon _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Donald Bruce Stewart
On 1/10/07, Malcolm Wallace <[hidden email]> wrote:
> Actually, I'm pretty sure that most Haskell RTS implementations have a > finalizer attached to all file handles. Once the file handle is no > longer reachable from the program graph (even if its data has not been > fully consumed), the GC will close the file (via the finalizer) before > reaping the memory associated with the handle. That's not the point. The GC will only close the file when the heap is under pressure. It does not aggressively close the file, so the file may stay open for longer than the user likes. For a read-only operation, this shouldn't matter, however on some platforms an open file handle can prevent deletion of the file. -- Taral <[hidden email]> "You can't prove anything." -- Gödel's Incompetence Theorem _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Taral wrote:
> For a read-only > operation, this shouldn't matter, however on some platforms an open > file handle can prevent deletion of the file. You'd be referring to Windows, then, where you can't rename or remove a file if someone has opened it. A partial defence against this is to pass FILE_SHARE_DELETE to CreateFile, if your Haskell runtime is using the win32 file API. The semantics are a bit strange, but it's less hostile than the default behaviour. If your favourite runtime is going through stdio, you're stuck (the strong-stomached can use CreateFile, then turn the handle into a FILE*, but this behaves peculiarly). <b _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
| Powered by Nabble | Edit this page |
