tags:

views:

486

answers:

4

Does anyone know where I can find a Stream splitter implementation?

I'm looking to take a Stream, and obtain two separate streams that can be independently read and closed without impacting each other. These streams should each return the same binary data that the original stream would. No need to implement Position or Seek and such... Forward only.

I'd prefer if it didn't just copy the whole stream into memory and serve it up multiple times, which would be fairly simple enough to implement myself.

Is there anything out there that could do this?

+2  A: 

Not out of the box.

You'll need to buffer the data from the original stream in a FIFO manner, discarding only data which has been read by all "reader" streams.

I'd use:

  • A "management" object holding some sort of queue of byte[] holding the chunks to be buffered and reading additional data from the source stream if required
  • Some "reader" instances which known where and on what buffer they are reading, and which request the next chunk from the "management" and notify it when they don't use a chunk anymore, so that it may be removed from the queue
Lucero
+1  A: 

I do not think you will be able to find a generic implementation to do just that. A Stream is rather abstract, you don't know where the bytes are coming from. For instance you don't know if it will support seeking; and you don't know the relative cost of operations. (The Stream might be an abstraction of reading data from a remote server, or even off a backup tape !).

If you are able to have a MemoryStream and store the contents once, you can create two separate streams using the same buffer; and they will behave as independent Streams but only use the memory once.

Otherwise, I think you are best off by creating a wrapper class that stores the bytes read from one stream, until they are also read by the second stream. That would give you the desired forward-only behaviour - but in worst case, you might risk storing all of the bytes in memory, if the second Stream is not read until the first Stream has completed reading all content.

driis
What's the application of this?
headsling
+1  A: 

You can't really do this without duplicating at least part of the sourse stream - mostly due to the fact that if doesn't sound like you can control the rate at which they are consumed (multiple threads?). You could do something clever regarding one reading ahread of the other (and thereby making the copy at that point only) but the complexiy of this sounds like it's not worth the trouble.

headsling
not to mention that if it is used in a multi threaded scenario you stop the OS/platform from using it's own intrinsic mechanisms for having multiple readers of the same file.If used in memory the worst case will always be that you might have to copy the entire stream anyway so trying something like this is possibly a lot of effort for noting... would a push to multiple consumers model work better perhaps
ShuggyCoUk
+1  A: 

This could be tricky without risking keeping everything buffered in memory (if the streams are at BOF and EOF respectively).

I wonder whether it isn't easier to write the stream to disk, copy it, and have two streams reading from disk, with self-deletion built into the Close() (i.e. write your own Stream wrapper around FileStream).

Marc Gravell