[Haskell-cafe] ANN: cautious-file 0.1.1: Ways to write a file cautiously, to avoid data loss

Robin Green greenrd at greenrd.org
Sun Jul 19 18:35:34 EDT 2009

I'm pleased to announce the first public release of cautious-file:


This library currently provides a writeFile function that is intended to
have three advantages over Prelude.writeFile:

1. There was a controversy a few months ago about the new Linux
filesystem ext4, and how existing applications which write certain files
naively might expose their users to the risk of data loss after a crash
or power failure. (Actually, it turns out that this is not a
new issue - certain other filesystems or filesystem mount
options can cause similar issues, but few people made a fuss about it.)
cautious-file uses the recommended way of writing a file on POSIX (more
or less). On non-POSIX systems (i.e. Windows), it tries to do something
sensible, but it may not be the best way to do it, and I've only ran
the tests on Linux.

2. With almost any filesystem or operating system, saving a file by
overwriting it exposes the user to the risk of data loss if there is a
crash or power failure. cautious-file creates a temporary file first
and only overwrites the file when it has finished writing (on POSIX
systems with sane filesystems, at least).

3. Prelude.writeFile is supposed to lock files so that they at least
cannot be written to simultaneously in multiple threads. This is good
for safety, but might lead to avoidable problems with IO exceptions when
one thread tries to open a file for writing which is still being
written to by another thread. Again, the use of a randomly-named
temporary file avoids this problem (not with certainty, but with a high
probability, which is good enough for some applications). It does not
prevent all file-related race conditions (nothing with its type
signature could!), but if you are sure you don't care which thread
wins, you should be able to use cautious-file's writeFile.

A variant, writeFileWithBackup, also allows you to supply a custom
backup computation to backup old copy(ies) of the destination file
(which is not necessary with Prelude.writeFile, because you can just do
it before you call Prelude.writeFile, but is necessary with

cautious-file is obviously not appropriate for all circumstances - for
instance, it's not needed for writing truly temporary files. But of
course if it's close to what you need, you can adapt it (and send me
a patch if you like).

There is a test runner that can be run by running "runhaskell
Setup.lhs test" or "cabal test" in a built copy of the source
distribution. The tests do not actually verify that data loss doesn't
happen if there's a crash! Indeed, attention should be drawn to the
standard BSD license - despite the name "cautious-file", there is no
warranty. If in doubt, I suggest you take a close look at the source
code - it's very short.

I'd appreciate comments, patches, pointers to Haskell code that does the
same thing already, etc.


More information about the Haskell-Cafe mailing list