I have a situation in which I am using multiple streams to download a zipped file via http. To do so I need to use multiple streams. I.e. get a web response stream, read into a binary reader stream, write to memory stream using binary writer stream etc etc.
As it's all a bit complicated and nasty I have split everything up into small functions to make it read a bit nicer, but I have a bit of a provlem with the readStreamIntoMemoryStream
function which I am calling from the public DownloadCsvReport
function, see below:
public IEnumerable<string> DownloadCsvReport(string reportDownloadUrl)
{
using (Stream responseStream = creatDownloadWebRequest(reportDownloadUrl))
using (MemoryStream memoryStream = readStreamIntoMemoryStream(responseStream))
{
setMemoryStreamToBegining(memoryStream);
ZipEntry zipEntry = getZippedFileFromMemoryStream(memoryStream);
return convertZippedFileToCsvRows(zipEntry);
}
}
private MemoryStream readStreamIntoMemoryStream(Stream webResponseStream)
{
var memoryStream = new MemoryStream();
var binaryWriter = new BinaryWriter(memoryStream);
var binaryReader = new BinaryReader(webResponseStream);
while (true)
{
byte[] buffer = binaryReader.ReadBytes(BufferSize);
binaryWriter.Write(buffer);
if (buffer.Length != BufferSize)
{
return memoryStream;
}
}
}
The thing I am unsure about is whether the BinaryWriter
and BinaryReader
streams from the private function will be disposed of when the MemoryStream
is when the public method loses scope? If not and I wrapped these stream's in using statements within the private method, would it not throw an exception when I tried to access the MemoryStream
in the public method?
The thing I am unsure about is whether the BinaryWriter and BinaryReader streams from the private function will be disposed of when the MemoryStream is when the public method loses scope?
The thing is, BinaryWriter
and BinaryReader
are not streams.
They act upon the underlying stream which, in your case, is the memoryStream
.
So, as long as you close your memoryStream
and the outer responseStream
, everything is fine.
Edit:
In fact, take a look at their source code:
protected virtual void Dispose(bool disposing)
{
if (disposing)
OutStream.Close();
}
As you can see, all it does is call Dispose
on the underlying stream. Your current code already does that - so there's no need to dispose of the writer/reader. It would be redundant.