
Ben wrote:
this throws a permission denied exception, presumably because the file is still open when the removeFile is called.
Yes. The file handle opened by encodeFile won't be closed until its finalizer is run. There is no guarantee that the finalizer will be run immediately. In fact, you can usually rely on the finalizer *not* running immediately, because the GC has to kick in, notice that the handle is dead, and hand it to the finalizer thread. It's actually possible that your finalizer could not run at all.
i've grovelled the source of Data.Bytestring.Lazy and all but i can't seem to understand the "right" way to make this work.
Don't use encodeFile at all. Instead, write your own: import Data.Binary (Binary, encode) import Control.Exception (bracket) import qualified Data.ByteString.Lazy as L import System.IO (IOMode(..), hClose, openFile) encodeFile :: Binary a => FilePath -> a -> IO () encodeFile path = bracket (openFile path WriteMode) hClose . flip L.hPut . encode