In what order should files be clesed

T

Tony Johansson

Hi!

I have this simple program where I use two classes to hande files.
Is this the correct order to close files that is opened ?

static void Main()
{
string s= "tonytest";
long l = 123;
FileStream fs = new FileStream("test.bin",FileMode.Create);
BinaryWriter binw = new BinaryWriter(fs);
binw.Write(s);
binw.Write(l);
binw.Close();
fs.Close();
}

//Tony
 
M

Mr. Arnold

Tony said:
Hi!

I have this simple program where I use two classes to hande files.
Is this the correct order to close files that is opened ?

static void Main()
{
string s= "tonytest";
long l = 123;
FileStream fs = new FileStream("test.bin",FileMode.Create);
BinaryWriter binw = new BinaryWriter(fs);
binw.Write(s);
binw.Write(l);
binw.Close();
fs.Close();
}

//Tony

I like a good flush every now and then.

http://msdn.microsoft.com/en-us/library/2bw4h516.aspx
 
P

Patrice

Correct,

The usual pattern is to close things in the reverse order they were opened
at least for clarity...
 
H

Harlan Messinger

Tony said:
Hi!

I have this simple program where I use two classes to hande files.
Is this the correct order to close files that is opened ?

static void Main()
{
string s= "tonytest";
long l = 123;
FileStream fs = new FileStream("test.bin",FileMode.Create);
BinaryWriter binw = new BinaryWriter(fs);
binw.Write(s);
binw.Write(l);
binw.Close();
fs.Close();
}

Functionally, it doesn't make the slightest difference what order you
open or close the files in. Organizationally, I think the nested
approach in your example is a good one to follow, but you could also
just as well have the writer "outside" the reader, insofar as, in
another app, you might open one output stream to be written to based on
the contents of multiple input streams.
 
P

Peter Duniho

Tony said:
Hi!

I have this simple program where I use two classes to hande files.
Is this the correct order to close files that is opened ?

static void Main()
{
string s= "tonytest";
long l = 123;
FileStream fs = new FileStream("test.bin",FileMode.Create);
BinaryWriter binw = new BinaryWriter(fs);
binw.Write(s);
binw.Write(l);
binw.Close();
fs.Close();

A better pattern is this:

using(FileStream fs = new FileStream("test.bin",FileMode.Create))
using(BinaryWriter binw = new BinaryWriter(fs))
{
binw.Write(s);
binw.Write(l);
}

That implicitly closes/disposes the objects in reverse order of creation.

But actually, BinaryWriter should be disposing not just itself, but also
the stream object given to it. So technically, the stream object winds
up disposed when you dispose the BinaryWriter.

Pete
 
J

Jeff Johnson

I have this simple program where I use two classes to hande files.
Is this the correct order to close files that is opened ?

static void Main()
{
string s= "tonytest";
long l = 123;
FileStream fs = new FileStream("test.bin",FileMode.Create);
BinaryWriter binw = new BinaryWriter(fs);
binw.Write(s);
binw.Write(l);
binw.Close();
fs.Close();
}

Please note that you have not opened fileS, you have opened A file. A
BinaryWriter is being created over a FileStream, and all it is doing is
providing a friendly way of writing bytes to the underlying stream. No
additional files are opened by the writer. Your question should really be
"In which order should I close and/or dispose of these classes?"
 
A

Anthony Wieser

Peter Duniho said:
A better pattern is this:

using(FileStream fs = new FileStream("test.bin",FileMode.Create))
using(BinaryWriter binw = new BinaryWriter(fs))
{
binw.Write(s);
binw.Write(l);
}

That implicitly closes/disposes the objects in reverse order of creation.

But actually, BinaryWriter should be disposing not just itself, but also
the stream object given to it. So technically, the stream object winds up
disposed when you dispose the BinaryWriter.

I'm confused. Why would you expect BinaryWriter to close the steram handed
to it?

Maybe I want to attach it to something else (a reader, a different binary
writer, etc).
It doesn't seem to be documented on MSDN that it does this. Do you have a
pointer to somewhere that suggests it does?
 
P

Peter Duniho

Anthony said:
[...]
I'm confused. Why would you expect BinaryWriter to close the steram
handed to it?

Because it's documented to do so. Try it.
Maybe I want to attach it to something else (a reader, a different
binary writer, etc).
It doesn't seem to be documented on MSDN that it does this. Do you have
a pointer to somewhere that suggests it does?

The MSDN docs do specifically say this. The docs for Dispose() are a
bit round-about, saying only that "managed resources" are released (and
you have to infer that from the fact that Dispose() calls Dispose(bool),
passing "true"). But the docs for Close() specifically state that the
underlying stream is disposed, _and_ that Close() simply calls
Dispose(bool), passing "true".

Pete
 
A

Anthony Wieser

Peter Duniho said:
Anthony said:
[...]
I'm confused. Why would you expect BinaryWriter to close the steram
handed to it?

Because it's documented to do so. Try it.
Maybe I want to attach it to something else (a reader, a different binary
writer, etc).
It doesn't seem to be documented on MSDN that it does this. Do you have
a pointer to somewhere that suggests it does?

The MSDN docs do specifically say this. The docs for Dispose() are a bit
round-about, saying only that "managed resources" are released (and you
have to infer that from the fact that Dispose() calls Dispose(bool),
passing "true"). But the docs for Close() specifically state that the
underlying stream is disposed, _and_ that Close() simply calls
Dispose(bool), passing "true".

Pete

Thanks for the clarification. So if I want the stream to remain open, I
shouldn't enclose the Writer in a using block, if I understand you and the
documentation correctly.

I have to admit, the documentation confuses me sometimes. For instance,
close is described this way:
"This implementation of Close calls the Dispose method passing a true
value". Initially, that doesn't preclude close from doing some work and not
Dispose. however further reading on the definition of Dispose says that
when implementing dispose, it should call Dispose on all objects it
allocates. I assume what this really means is that it does it on all
objects it contains, regardless of who allocated it, correct?

--
Anthony Wieser
Wieser Software Ltd



Anthony Wieser
Wieser Software Ltd
 
P

Peter Duniho

Anthony said:
Thanks for the clarification. So if I want the stream to remain open, I
shouldn't enclose the Writer in a using block, if I understand you and
the documentation correctly.

That is correct. You also will want to make sure you call Flush() on
the writer before you attempt to use the stream in any other way, to
ensure that the writer has no remaining buffered data to send to the stream.

Even then, I would be _very_ wary of using a stream with multiple
writers of any sort. If you need to mix data types on a stream, I would
advise using BinaryWriter (which does have some text support), or do all
of your conversions to binary manually and write directly to the stream.
I have to admit, the documentation confuses me sometimes. For instance,
close is described this way:
"This implementation of Close calls the Dispose method passing a true
value". Initially, that doesn't preclude close from doing some work and
not Dispose. however further reading on the definition of Dispose says
that when implementing dispose, it should call Dispose on all objects it
allocates. I assume what this really means is that it does it on all
objects it contains, regardless of who allocated it, correct?

That's correct. And yes, the documentation isn't always very clear. I
would suggest and request that when you run across documentation pages
that don't seem clear to you, submit some feedback to Microsoft using
the link on the page. They do occasionally review the feedback and I've
seen the documentation gradually improve this way.

Pete
 

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