From .NET 4.5 on, there is the Stream.CopyToAsync
method
input.CopyToAsync(output);
This will return a Task
that can be continued on when completed, like so:
await input.CopyToAsync(output)
// Code from here on will be run in a continuation.
Note that depending on where the call to CopyToAsync
is made, the code that follows may or may not continue on the same thread that called it.
The SynchronizationContext
that was captured when calling await
will determine what thread the continuation will be executed on.
Additionally, this call (and this is an implementation detail subject to change) still sequences reads and writes (it just doesn't waste a threads blocking on I/O completion).
From .NET 4.0 on, there's is the Stream.CopyTo
method
input.CopyTo(output);
For .NET 3.5 and before
There isn't anything baked into the framework to assist with this; you have to copy the content manually, like so:
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[32768];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write (buffer, 0, read);
}
}
Note 1: This method will allow you to report on progress (x bytes read so far ...)
Note 2: Why use a fixed buffer size and not input.Length
? Because that Length may not be available! From the docs:
If a class derived from Stream does not support seeking, calls to Length, SetLength, Position, and Seek throw a NotSupportedException.
A Duplex stream can be thought of a readable stream with a writable stream. Both are independent and each have separate internal buffer. The reads and writes events happen independently.
Duplex Stream
------------------|
Read <----- External Source
You ------------------|
Write -----> External Sink
------------------|
You don't get what you write. It is sent to another source.
A Transform stream is a duplex where the read and write takes place in a causal way. The end points of the duplex stream are linked via some transform. Read requires write to have occurred.
Transform Stream
--------------|--------------
You Write ----> ----> Read You
--------------|--------------
You write something, it is transformed, then you read something.
Best Answer
Sink
andStream
both are parts of theStreamController
. You add a data to theStreamController
usingSink
which can be listened via theStream
.Example:
Usage:
Whenever a data is added to the stream via sink, it will be emitted which can be listened using the listen method.
You can perform a various number of actions before the stream is emitted.
transform
method is an example which can be used to transform the input data before it gets emitted.