Introduction
CoStream
is a bufferless alternative for PipeStream
.
Background
In a producer/consumer pattern, if we know that there is a consumer that is guaranteed to read the stream
to the end, or dispose it in case it can't, the synchronizing stream
doesn't need to maintain its own internal buffer, relying entirely on the buffers provided by the caller(s) of the Read
method. In the Read
method, CoStream
saves the reference to the target buffer and waits until it is filled. The Write
method, on the other hand, copies data from the source buffer to the target one, signals to the reader if the buffer is ready and either waits for another Read
call if there are some unconsumed data left in the source buffer, or returns to the Write
caller.
Using the Code
CoStream
cannot be used in a single thread. There should be at least two, reading and writing threads. Both are required to close (or dispose) the stream
so that the counterpart could resume at the end.
The test program that you will find in the attached archive loads some XML file in the XmlDocument
, then writes it to the instance of the CoStream
:
static CoStream costream = new TestCoStream();
static string outpath;
static void Main(string[] args)
{
XmlDocument doc = new XmlDocument();
doc.Load(args[0]);
outpath = args[1];
var reading_thread = new Thread(ReaderBody);
reading_thread.Start();
using (var pipe = XmlWriter.Create(costream, new XmlWriterSettings { CloseOutput = true }))
doc.Save(pipe);
reading_thread.Join();
}
The reading thread simply copies it to the output file:
static void ReaderBody()
{
using (var reader = XmlReader.Create(costream, new XmlReaderSettings { CloseInput = true }))
using (var writer = XmlWriter.Create(outpath))
writer.WriteNode(reader, false);
}
TestCoStream
class overrides Read
, Write
and Flush
methods of the CoStream
to show what happens in the background.
Running the program with a sample XML input file that is longer than the internal buffers used by default implementations of the XmlReader
and XmlWriter
(for example, this one: http://www.w3.org/2001/xml.xsd) will result in something like this:
<Writing 6143 bytes.
>Reading 4096 bytes.
>4096 bytes read.
>Reading 4096 bytes.
<Written.
<Writing 2163 bytes.
>4096 bytes read.
>Reading 4096 bytes.
<Written.
<Flushing.
>114 bytes read.
>Reading 4096 bytes.
<Writing 0 bytes.
<Written.
<Flushing.
<Writing 0 bytes.
<Written.
<Flushing.
>0 bytes read.
History