2

I am writing text to a System.IO.StreamWriter.

The underlying stream (specified in new StreamWriter(underlyingStream)) writes to a remote file. (I don't think its type is relevant, but for completeness' sake I'll mention it's a microsoft azure CloudBlobStream underlyingStream).

Now, I wanted to extend this by also writing an additional compressed file with the same content, but by using GZipOutputStream compressedUnderlyingStream between the StreamWriter and a second CloudBlobStream.

I was looking for a way to specify both of the CloudBlobStreams as underlying streams of the StreamWriter. But I could not find a way. Does there exist some stream type that can combine two underlying streams? Or how can I otherwise approach this? Note I want everything to stay as streams to minimize amount of data in memory.

//disregard lack of using statements for this example's sake
CloudBlobStream blobStream = blob.OpenWrite();
CloudBlobStream compressedBlobStream = compressedBlob.OpenWrite();
GZipOutputStream compressorStream = new GZipOutputStream(compressedBlobStream);
//I make the streamwriter here for the regular blob,
///but how could I make the same streamwriter also write to the compressedBlob at the same time?
TextWriter streamWriter = new StreamWriter(blobStream, Encoding.UTF8);
David S.
  • 5,965
  • 2
  • 40
  • 77

1 Answers1

6

I can't think of one off the top of my head, but it would be trivial to write your own:

class MultiStream : Stream
{
    private List<Stream> streams;

    public Streams(IEnumerable<Stream> streams)
    {
        this.streams = new List<Stream>(streams);
    }

    ...

    public override void Write(byte[] buffer, int offset, int count)
    {
        foreach(Stream stream in streams)
            stream.Write(buffer, offset, count);
    }

    ...
}
PC Luddite
  • 5,883
  • 6
  • 23
  • 39
  • Thanks -- Any thoughts on what to do with the other properties though, such as `Length` and `Position`, I suppose they can be different depending on the kind of underlying stream? – David S. Feb 03 '17 at 16:44
  • @DavidS. Maybe show the minimum of of all lengths, and have a relative position depending on each starting position – PC Luddite Feb 03 '17 at 16:50
  • yeah maybe.. as a private implementation I suppose I could get away with throwing exception on those two properties as long as they're not used by the other streams or by me – David S. Feb 03 '17 at 17:01
  • 1
    @DavidS. I wouldn't want to throw exceptions on those properties, since they could be called by StreamWriter/Reader. I would just return "safe" values, like the minimum length of all streams. That would guarantee the position would never go past the end of a stream. Keeping track of the position would be trickier though. – PC Luddite Feb 03 '17 at 17:18
  • 4
    Just in case somebody would need the implementation: https://gist.github.com/tenbits/ac5441e84b7983e0e17f39be172e87f9 – tenbits May 02 '18 at 15:31