Cristian Diaconescu
Cristian Diaconescu

Reputation: 35731

.NET IO: Can I force a BinaryWriter (or a FileStream) to always flush to disk?

I need behaviour similar to Java's RandomAccessFile(path, "rws") method, namely flushing data to disk as soon as it is written to the file.

I lean towards using BinaryWriter for my purposes, but it doesn't have a way to specify the flushing behaviour.

Any suggestions?

Upvotes: 1

Views: 1706

Answers (4)

John Rusk - MSFT
John Rusk - MSFT

Reputation: 643

See also the WriteThrough option, which you can provide when creating a file stream. It causes your stream to skip all OS-level buffering. I think however, that there is still buffering within the stream, at the size specified in the stream's constructor (or 4k if not specified). So I think that with WriteThrough the stream object itself buffers until the specified buffer size is full, and then immediately writes through to the underlying storage.

Ayende has a write-up here: https://ayende.com/blog/163073/file-i-o-flush-or-writethrough

Upvotes: 0

flindeberg
flindeberg

Reputation: 5027

I'd recommend writing an extension method as a wrapper:

public static class MyBinaryWriterExtensions {
  public static void WriteAndFlush(this BinaryWriter writer, byte[] data) {
     writer.Write(data);
     // Slow! Disk access is at least 10 ms! (for a fast disk)
     writer.Flush();
  }
}

This would be called like this:

BinaryWriter bw = ... // Getting your writer somehow
byte[] data = ... // your data
bw.WriteAndFlush(data); // Will write and flush!

Or are you in need of some kind of atomicity?

Upvotes: 0

VladL
VladL

Reputation: 13043

You can put every writer into 'using' which will Dispose() it at the end

using (BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create)))
        {
            writer.Write(1.250F);
            writer.Write(@"c:\Temp");
            writer.Write(10);
            writer.Write(true);
        }

For the text you can use File.WriteAllText function which doesn't need flush at all

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1064324

BinaryWriter is not sealed, and all of the Write methods are virtual. You could override them and add a call to Flush, for example:

public override void Write(byte value)
{
    base.Write(value);
    Flush(); // which is just: this.OutStream.Flush();
}

However! In most cases this would be really bad for performance. I don't recommend it.

If you are using a StreamWriter or similar, then just set AutoFlush to true; job done; but again - this could really hurt performance.

Upvotes: 1

Related Questions