Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream that has separate write and read positions

Tags:

c#

stream

I want to emulate a network-type stream on a single PC.

I've done this by creating a Stream that takes in 2 underlying streams, one to read from and another to write to.

I then create 2 instances of this class swapping the 2 streams. Currently I'm using MemoryStreams as the 2 underlying streams.

The trouble i have now is that if I write X bytes to a MemoryStream then its position will be X and if i then do a Read I get no data, as i'm at the end of the stream.

Given that I'll typically be doing a couple of reads/writes (so can't just reset the postion to 0 after every write) what Stream can i use to get this behaviour?

Effectively I want a sort of byte queue that I can write to and read to in the form of a stream.

i.e. (ignoring actual method arguments)

MyStream.Write({ 1, 2, 3, 4, 5, 6 });
MyStream.Write({ 7, 8 });
MyStream.Read(3) // Returns { 1, 2, 3 }
MyStream.Read(4) // Returns { 4, 5, 6, 7 }
like image 365
George Duckett Avatar asked Apr 27 '12 14:04

George Duckett


People also ask

Can we read write a stream simultaneously?

This is entirely possible, no problem; but you wouldn't use the same stream, you would use two different ones, and pipe data from the input to the output in a loop.

What does stream positions mean?

The file position of a stream describes where in the file the stream is currently reading or writing. I/O on the stream advances the file position through the file. On GNU systems, the file position is represented as an integer, which counts the number of bytes from the beginning of the file. See File Position.

How do I write from one stream to another?

CopyTo(Stream, Int32) Reads the bytes from the current stream and writes them to another stream, using a specified buffer size. Both streams positions are advanced by the number of bytes copied.

What is stream write?

createReadStream method. A writable stream is an abstraction for a destination to which data can be written. An example of that is the fs. createWriteStream method. A duplex streams is both Readable and Writable.


1 Answers

It's actually a lot simpler than I thought (in my case anyway).
I simply restore/record the read/write positions before performing any operation:

public class QueueStream : MemoryStream
{
    long ReadPosition;
    long WritePosition;

    public QueueStream() : base() { }

    public override int Read(byte[] buffer, int offset, int count)
    {
        Position = ReadPosition;

        var temp = base.Read(buffer, offset, count);

        ReadPosition = Position;

        return temp;
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        Position = WritePosition;

        base.Write(buffer, offset, count);

        WritePosition = Position;
    }
}
like image 88
George Duckett Avatar answered Sep 20 '22 04:09

George Duckett