Haskell won't actually read the file unless you need the contents of the file. In order to ensure that the file contents are read before it gets close, you need to actually perform an operation that will force evaluation of the file. Haskell will read the file then to perform whatever operation you specify.The function below always returns "", rather than the file's contents. _Real World Haskell_ touches on how laziness can make this problimatic, without really giving a solution, other than throwing in a putStr to force evaluation, which can't be done here. How can I make hGetContents strict, to ensure the file contents are really read before it gets closed? readFile' file = do f <- openFile file ReadMode -- locking will go here s <- hGetContents f hClose f return s
You should go to haskell.org/hoogle, and search openFile, or check out the Haskell98 report, but I'm under the impression that ghc locks the file for you when you open the file.:Also, I noticed that opening a file and locking it involves a very verbose seeming dance. (It's 2 lines of code in most other languages.) Does this indicate that few people bother with file locking in Haskell and so it still has these rough edges, or that there's a better way to do it that I have not found yet? openLocked file = do handle <- openFile file ReadMode lockfd <- handleToFd handle -- closes handle waitToSetLock lockfd (ReadLock, AbsoluteSeek, 0, 0) handle' <- fdToHandle lockfd return handle'
Implementations should enforce as far as possible, at least locally to the Haskell process, multiple-reader single-writer locking on files. That is, there may either be many handles on the same file which manage input, or just one handle on the file which manages output. If any open or semi-closed handle is managing a file for output, no new handle can be allocated for that file. If any open or semi-closed handle is managing a file for input, new handles can only be allocated if they do not manage output. Whether two files are the same is implementation-dependent, but they should normally be the same if they have the same absolute path name and neither has been renamed, for example.
Error reporting: the openFile computation may fail with isAlreadyInUseError if the file is already open and cannot be reopened; isDoesNotExistError if the file does not exist; orisPermissionError if the user does not have permission to open the file