Как мне "раскошелиться" на поток в.NET?
Как обсуждалось ранее, когда 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 ответов
Благодаря нескольким, кто предложил ToArray, меня привели к правильному ответу, а именно: M.GetBuffer. ToArray не так уж плохо, но это
- делает копию
- получает только часть буфера
GetBuffer просто получает ссылку на нижележащий байт [], что я и ищу.
Вам лучше получить базовый буфер byte[], используя
byte[] buffer = ms.GetBuffer();
А затем скопируйте байтовые данные, используя метод Array.Copy(). Вы можете создать новый поток с ним.
Вы можете использовать такие вещи, как 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
}
Вы можете:
- Вызовите M.ToArray(), чтобы получить поток в виде массива байтов.
- Подкласс BinaryWriter и переопределить метод Dispose, чтобы предотвратить закрытие дочернего потока
Просто добавьте это здесь, очень простым решением было бы не 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().
Возможно, это не лучшее решение, но стоит отметить, что читатели и писатели не нуждаются в утилизации сами.
Несколько наивный подход заключается в использовании
byte buf[] = MemoryStream.ToArray();
Копировать содержимое потока в байтовый массив. Вы можете превратить его обратно в поток с
MemoryStream ms = new MemoryStream(buf);
В соответствии с этим M.Clone(); должно сработать. Но я могу ошибаться...