File.IO

  • Thread starter Thread starter PJ
  • Start date Start date
P

PJ

I have an open FileStream and I open a BinaryWriter on it. After writing to
this file, I want to read it to another stream.

FileStream fs = new FileStream(Path.GetTempFileName());
BinaryWriter bw = new BinaryWriterer(fs);

// write data to a filestream

bw.Close();
fs.Position = 0; // ** Exception, Object is disposed
BinaryReader br = new BinaryReader(fs);

// read file and send to another stream

However, apparently closing the BinaryWriter closes the FileStream. I don't
understand why closing a writer on a stream closes the stream itself.
What's the best way to accomplish what I am trying to do?

TIA~ PJ
 
PJ said:
I have an open FileStream and I open a BinaryWriter on it. After writing to
this file, I want to read it to another stream.

FileStream fs = new FileStream(Path.GetTempFileName());
BinaryWriter bw = new BinaryWriterer(fs);

// write data to a filestream

bw.Close();
fs.Position = 0; // ** Exception, Object is disposed
BinaryReader br = new BinaryReader(fs);

// read file and send to another stream

However, apparently closing the BinaryWriter closes the FileStream. I don't
understand why closing a writer on a stream closes the stream itself.

Because for almost all the time, that's actually what you want. At
least, it's almost always what *I* want :)
What's the best way to accomplish what I am trying to do?

Hmm... not sure. It would be fairly easy to write a
NonClosingFilterStream or something similar, which passes through all
method calls apart from Close. I *think* that would do it...
 
PJ,

The behavior of the BinaryWriter class you are describing is by design. If
you read the documentation it says: "[BinaryWriter.Close()] Closes the
current BinaryWriter and the underlying stream.". Actually all the Close()
method is doing is call the Dispose() method with true as only parameter.
When the parameter equal true the Dispose() method closes the stream
associated with it.

If you delay closing the BinaryWriter object you will be able to read from
the file via the BinaryReader object created from the same file stream.

A more complex solution would be to create a new class inheriting from
BinaryWriter, and overload the Close() method so that it won't close the
file stream. You will have to close it manually.

Gabriele
 
Overrloading the Close() method w/ a boolean parameter seems like the least
complex and the way they should have designed it to me. I guess I should
read the documentation more, as I have always called .Close() on the stream
as well.

thx! PJ

Gabriele G. Ponti said:
PJ,

The behavior of the BinaryWriter class you are describing is by design. If
you read the documentation it says: "[BinaryWriter.Close()] Closes the
current BinaryWriter and the underlying stream.". Actually all the Close()
method is doing is call the Dispose() method with true as only parameter.
When the parameter equal true the Dispose() method closes the stream
associated with it.

If you delay closing the BinaryWriter object you will be able to read from
the file via the BinaryReader object created from the same file stream.

A more complex solution would be to create a new class inheriting from
BinaryWriter, and overload the Close() method so that it won't close the
file stream. You will have to close it manually.

Gabriele

PJ said:
I have an open FileStream and I open a BinaryWriter on it. After
writing
to
this file, I want to read it to another stream.

FileStream fs = new FileStream(Path.GetTempFileName());
BinaryWriter bw = new BinaryWriterer(fs);

// write data to a filestream

bw.Close();
fs.Position = 0; // ** Exception, Object is disposed
BinaryReader br = new BinaryReader(fs);

// read file and send to another stream

However, apparently closing the BinaryWriter closes the FileStream. I don't
understand why closing a writer on a stream closes the stream itself.
What's the best way to accomplish what I am trying to do?

TIA~ PJ
 
Because for almost all the time, that's actually what you want. At
least, it's almost always what *I* want :)

It occurred to me that maybe it sounds like I'm trying to write a virus,
lol. The reason I need to do this is that I am compressing a set of files
and then sending it out to an HTTP response stream. I was sending the
compressed bytes directly to the stream as the compression was taking
place.....but w/out the compression being complete, I have no way of setting
the Content-Length header, so the d/l dialog box does not show a %
completion ( unnacceptable I'm told ).

thx! PJ
 
PJ said:
It occurred to me that maybe it sounds like I'm trying to write a virus,
lol. The reason I need to do this is that I am compressing a set of files
and then sending it out to an HTTP response stream. I was sending the
compressed bytes directly to the stream as the compression was taking
place.....but w/out the compression being complete, I have no way of setting
the Content-Length header, so the d/l dialog box does not show a %
completion ( unnacceptable I'm told ).

In that case, given that effectively you've *got* to buffer the whole
thing anyway, you could just write to a MemoryStream first, find the
length of that, and then dump the contents of the memory stream to the
real response.
 
I don't understand what you're saying, I don't have to buffer the whole file
at all. The Content-Length header is the length of the content only, not
the whole response including the headers. The fs.Length property gives me
the value for that header w/out buffering the whole file.
 
Back
Top