Search code examples
c#usingstreamwriter

Writing into the same file with two `using` statements and two writers


I am trying to open a file in c#, then write some text into it, and conclude by dumping a compression of a bytes array into the same file. So, the file I want to create is something like

sometextinascii
somemoretextinascii
BUNCHOFNONHUMANREADABLEBYTES

and what I did was the following:


// Code where we get values of the following variables:
// string filename
// Byte[] buffer
using (FileStream file = new(filename, FileMode.Create, FileAccess.Write))
{
    using (StreamWriter writer = new(file))
    {
        writer.WriteLine("sometext");
        writer.WriteLine("somemoretext");
    }
    using (GZipStream zipStream = new(file, CompressionMode.Compress))
    {
        zipStream.Write(buffer, 0, buffer.Length);
    }
}

but this does not work. When I run this code, I get the error

System.ArgumentException: 'Stream does not support writing. (Parameter 'stream')'

when the variable zipStream is being created.

What I don't understand is that if I remove the StreamWriter part of the code, then the code works fine. So, I have two questions:

  1. Does the StreamWriter somehow close the file once it closes itself?
  2. If yes, how can I prevent that? If no, what is the cause of my error?

Solution

  • By default, StreamWriter closes the target Stream when disposed, which means that it no longer reports as writable, which is why this error is showing. You can fix this by using the constructor that takes an optional bool:

    using (StreamWriter writer = new(file, leaveOpen: true))
    

    However, I wonder whether it is easier to simply not use StreamWriter and deal with the Encoding logic directly.

    Note that it doesn't make much sense to write prefix data like this before a GZipStream on the same file, unless you're also going to unwrap this yourself manually too when reading; it will no longer be a valid gzip payload otherwise.