Thursday, December 06, 2007
I've been playing with my fresh copy of Vista Ultimate - which I am surprised to find that I absolutely love.

Being a big fan of System.Transactions, I naturally wanted to use it with Vista's TxF (Transactional NTFS) file system. But unlike the data libraries, the file APIs don't auto-enlist in the transaction. In fact, there are only COM / PInvoke APIs currently.

There is a nice article about how to work with these APIs in the MSDN article: "NTFS: Enhance Your Apps With File System Transactions". But I was unimpressed with the managed wrapper they created there. In particular, I don't like that the lifetime of the file stream is not forced to be part of a client initiated transaction scope. So I built my own transactional file stream in C#. With this TxFileStream class, you can write succinct code like this:

[Test]
public void ContentAddedDoesNotPersistsAfterRollbackTest()
{
    string fileName = "file3.txt";
    string originalContents = "First contents";
   
    using (TransactionScope scope = new TransactionScope())
    {
        string newContents = "Hello transacted NTFS.";
        using (StreamWriter sw = TxFileStream.CreateWriter(fileName))
        {
            sw.Write(newContents);
        }

        using (StreamReader sr = TxFileStream.CreateReader(fileName))
        {
            string text = sr.ReadToEnd();
            Assert.That(text, Is.EqualTo(newContents));
        }
        // no call to scope.Complete() forces a rollback.
    }

    Assert.That(File.Exists(fileName));
    Assert.That(File.ReadAllText(fileName),
        Is.EqualTo(originalContents));
}


Feel free to download the code and give it a spin!

    Kennedy.TxFiles.zip (36 KB)

Of course, my library comes with comprehensive unit tests. Look here first to figure out how out use the library.

Note: I fixed a bug in creating transactional StreamWriter's in append mode. Previously they partially overwrote the existing content.