0
votes

I've got a method that streams files by returning a System.IO.FileStream pointing to a file opened for reading. What I want to do at this point is store the stream into a System.IO.MemoryStream as well.

The simplest option would be to first read the FileStream into the MemoryStream, and then return the MemoryStream to the caller. However this means that I'll have to buffer the entire file into memory before returning, thereby delaying the streaming response to the caller.

What I'd like to do (if possible) is read the FileStream into a MemoryStream and also stream it to the caller simultaneously. This way, the file doesn't have to be buffered before being returned, and still ends up getting stored into a MemoryStream.

1
I've had a similar requirement so i developed a RecordStream which if you tell it to, saves every result from a Read command in an internal memory stream and has the option to be played back. Maybe its usefull, see: upreader.codeplex.com/SourceControl/changeset/view/… - Polity
@Polity: I'm not sure if that's what I'm looking for. I need to read the FileStream to a network stream and an internal MemoryStream simultaneously. - rafale

1 Answers

1
votes

You can create a custom implementation of the Stream class in which you write away the data red to a memory stream, or use my version of that which can be found at: http://upreader.codeplex.com/SourceControl/changeset/view/d287ca854370#src%2fUpreader.Usenet.Nntp%2fEncodings%2fRecordStream.cs

This can be used in the following way:

using (FileStream fileStream = File.Open("test.txt", FileMode.Open))
using (RecordStream recordStream = new RecordStream(fileStream))
{
    // make sure we record incoming data
    recordStream.Record();

    // do something with the data
    StreamReader reader = new StreamReader(recordStream);
    string copy1 = reader.ReadToEnd();

    // now reset 
    recordStream.Playback();

    // do something with the data again
    StreamReader reader = new StreamReader(recordStream);
    string copy2 = reader.ReadToEnd();

    Assert.AreEqual(cop1, copy2);
}

I Built this class particularly for Network stream but it works equally well with a fileStream and it only reads the file once without buffering it first before returning

A simple implementation would be

class RecordStream : Stream
{
    public Stream BaseStream { get; }

    public MemoryStream Record { get; }

    ....

    public override int  Read(byte[] buffer, int offset, int count)
    {
      int result = BaseStream.Read(buffer, offset, count);

        // store it
        Record.Write(buffer, offset, count);

        return result;
    }
}