Как мне «раскошелиться» на поток в .NET? - PullRequest
8 голосов
/ 28 октября 2009

Как и обсуждалось ранее , когда BinaryReader или BinaryWriter закрываются, базовый поток также закрывается (аааа). Рассмотрим следующую ситуацию: процедуре R передается MemoryStream, скажем, M; Я хотел бы написать кое-что в M, а затем передать его в другую подпрограмму для дополнительной обработки (не обязательно записи). Для удобства я бы хотел обернуть M в BinaryWriter, чтобы писать. После написания я закончил с BinaryWriter, но не с M.

void R(MemoryStream M)
{
    using (B = new BinaryWriter(M))
    {
        // write some stuff using B
    }

    S(M);  // now pass M to another routine for further processing
}

Но я не могу избавиться от BinaryStream, не закрыв M.

В: Есть ли способ сделать что-либо из следующего?

  • извлечь базовый байт [] из MemoryStream,
  • клонировать поток
  • вновь открыть поток после его закрытия

Ответы [ 7 ]

7 голосов
/ 28 октября 2009

Вам лучше получить базовый буфер byte [], используя

byte[] buffer = ms.GetBuffer();

А затем скопируйте байтовые данные, используя метод Array.Copy (). Вы можете создать новый поток с ним.

5 голосов
/ 28 октября 2009

Вы можете использовать такие вещи, как MiscUtil.IO.NonClosingStreamWrapper в MiscUtil , который упаковывает Stream и просто игнорирует Close / Dispose запросы Именно для этой цели.

void R(MemoryStream M)
{
    using (B = new BinaryWriter(new NonClosingStreamWrapper(M)))
    {
        // write some stuff using B
    }

    S(M);  // now pass M to another routine for further processing
}    
2 голосов
/ 28 октября 2009

Спасибо нескольким, кто предложил ToArray, меня привели к правильному ответу, а именно: M.GetBuffer. ToArray не так уж и плох, но он

  • делает копию
  • получает только часть буфера

GetBuffer просто получает ссылку на нижележащий байт [], и это то, чего я добиваюсь.

2 голосов
/ 28 октября 2009

Вы можете:

  • Вызовите M.ToArray (), чтобы получить поток в виде массива байтов.
  • Подкласс BinaryWriter и переопределение метода Dispose для предотвращения закрытия дочернего потока
1 голос
/ 28 октября 2009

Просто добавьте это здесь, очень простым решением было бы , а не для Dispose () писателя.

void R(MemoryStream M)
{
    B = new BinaryWriter(M);

    // write some stuff using B        
    B.Flush();
    S(M);  // now pass M to another routine for further processing
}

Теперь вам нужно только позаботиться о том, чтобы B оставался в области видимости, что будет во время R ().

Возможно, это не лучшее решение, но стоит отметить, что читателям и писателям не нужно утилизировать себя.

0 голосов
/ 28 октября 2009

По это M.Clone (); должно сработать. Но я могу ошибаться ...

0 голосов
/ 28 октября 2009

Несколько наивный подход - использовать

byte buf[] = MemoryStream.ToArray();

Для копирования содержимого потока в байтовый массив. Вы можете превратить его обратно в поток с помощью

MemoryStream ms = new MemoryStream(buf);
...