ensure buffer flushed to file

J

John A Grandy

I am writing data to binary files one value at a time.

I am finding that when my code finishes , the final file is missing its
final value.

How can I ensure that all values have been written ?


Here is the code I call ( for each file ) :


FileStream stream = File.Open( <file path>, FileMode.Create,
FileAccess.Write, FileShare.ReadWrite );
BinaryWriter writer = new BinaryWriter( stream );

// write a whole bunch of doubles
writer.Write( <double value> );

writer.Flush(); // do I need this ?
writer.Close();
stream.Flush(); // do I need this ?
stream.Close(); // do I need this ?
stream.Dispose(); // do I need this ?
 
P

Pavel Minaev

I am writing data to binary files one value at a time.

I am finding that when my code finishes , the final file is missing its
final value.

How can I ensure that all values have been written ?

Here is the code I call ( for each file ) :

FileStream stream = File.Open( <file path>, FileMode.Create,
FileAccess.Write, FileShare.ReadWrite );
BinaryWriter writer = new BinaryWriter( stream );

// write a whole bunch of doubles
writer.Write( <double value> );

writer.Flush();   // do I need this ?
writer.Close();
stream.Flush();   // do I need this ?
stream.Close();   // do I need this ?
stream.Dispose(); // do I need this ?

First of all, you should just use the "using" statement for both your
stream and your writer:

using (FileStream stream = File.Open( <file path>, FileMode.Create,
FileAccess.Write, FileShare.ReadWrite ))
using (BinaryWriter writer = new BinaryWriter( stream ))
{
...
}

As for the actual meaning of things, here's how it goes. Close() and
Dispose() do the same thing for both streams and readers. Closing a
stream also flushes it, so you don't need Flush before Close. Closing
a StreamWriter flushes it as well, but also closes the underlying
stream (which then flushes its own buffers, if any). All in all, you
only need to call Close on the writer, and "using" will do that for
you.

Note that closing a stream after it's already closed is a safe thing
to do, so the above double-using statement is ok (writer will be
closed by inner "using" and will close the stream, then outer using
will close it once again). Technically, you don't need the outer
"using", but it's best to write it anyway, as it is a consistent
pattern to do so for any localized IDisposable objects.
 
J

John A Grandy

Hi Pavel , and thanks for the response.

I actually simplified my code , the reason I am not using "using" is that I
actually decide what will be written externally and call into an instance of
my file-writer class to initiate the stream and the writer, then successive
calls to write each value , and also to finalize ( the flushing , closing ,
disposing portion of my code ).

It actually was my understanding from the MS docs that only
BinaryWriter.Close() is needed -- but as I am experiencing this problem with
my final data value not being written to file at the time I perform
BinaryWriter.Close() , I decided to post.

What other conditions could lead to a data value not being immediately
written to file when the associated BinaryWriter is closed ?


I am writing data to binary files one value at a time.

I am finding that when my code finishes , the final file is missing its
final value.

How can I ensure that all values have been written ?

Here is the code I call ( for each file ) :

FileStream stream = File.Open( <file path>, FileMode.Create,
FileAccess.Write, FileShare.ReadWrite );
BinaryWriter writer = new BinaryWriter( stream );

// write a whole bunch of doubles
writer.Write( <double value> );

writer.Flush(); // do I need this ?
writer.Close();
stream.Flush(); // do I need this ?
stream.Close(); // do I need this ?
stream.Dispose(); // do I need this ?

First of all, you should just use the "using" statement for both your
stream and your writer:

using (FileStream stream = File.Open( <file path>, FileMode.Create,
FileAccess.Write, FileShare.ReadWrite ))
using (BinaryWriter writer = new BinaryWriter( stream ))
{
...
}

As for the actual meaning of things, here's how it goes. Close() and
Dispose() do the same thing for both streams and readers. Closing a
stream also flushes it, so you don't need Flush before Close. Closing
a StreamWriter flushes it as well, but also closes the underlying
stream (which then flushes its own buffers, if any). All in all, you
only need to call Close on the writer, and "using" will do that for
you.

Note that closing a stream after it's already closed is a safe thing
to do, so the above double-using statement is ok (writer will be
closed by inner "using" and will close the stream, then outer using
will close it once again). Technically, you don't need the outer
"using", but it's best to write it anyway, as it is a consistent
pattern to do so for any localized IDisposable objects.
 
J

John A Grandy

Does anyone know why BinaryWriter does not offer an AutoFlush option ,
similar to StreamWriter.AutoFlush ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top