Одновременное хранение и возврат FileStream - PullRequest
0 голосов
/ 10 октября 2011

У меня есть метод потоковой передачи файлов, возвращающий System.IO.FileStream, указывающий на файл, открытый для чтения. На данный момент я хочу сохранить поток в System.IO.MemoryStream.

Самый простой вариант - сначала прочитать FileStream в MemoryStream, а затем вернуть MemoryStream вызывающей стороне. Однако это означает, что мне придется буферизовать весь файл в памяти перед возвратом, что приведет к задержке ответа потоковой передачи вызывающей стороне.

Что я хотел бы сделать (если это возможно), так это прочитать FileStream в MemoryStream и одновременно передать его вызывающей стороне. Таким образом, файл не нужно буферизовать перед возвратом, и он все равно заканчивается сохранением в MemoryStream.

1 Ответ

1 голос
/ 10 октября 2011

Вы можете создать собственную реализацию класса Stream, в которой вы записываете данные красного цвета в поток памяти, или использовать мою версию, которую можно найти по адресу: http://upreader.codeplex.com/SourceControl/changeset/view/d287ca854370#src%2fUpreader.Usenet.Nntp%2fEncodings%2fRecordStream.cs

Это можно использовать следующим образом:

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);
}

Я создал этот класс специально для сетевого потока, но он одинаково хорошо работает с fileStream и читает файл только один раз, не буферизуя его перед возвратом

Простая реализация будет

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;
    }
}
...