Como faço para “fork” um fluxo no .NET?
-
06-07-2019 - |
Pergunta
Como discutido antes , quando um BinaryReader ou BinaryWriter fica fechado, o seu fluxo subjacente ficar fechado, bem como (aargh). Considere a seguinte situação: a R
rotina é passado um MemoryStream, M
digamos; Eu gostaria de escrever algumas coisas para M
e passá-lo para outra rotina para mais processamento (não necessariamente escrita). Por conveniência, eu gostaria de embrulhar M
em um BinaryWriter para fazer a minha escrita. Depois de escrever, eu sou feito com o BinaryWriter mas não com 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
}
Mas, eu não posso dispor do BinaryStream sem fechar M
.
Q:? Existe uma maneira de fazer qualquer um dos seguintes
- extrair o byte subjacente [] a partir de um MemoryStream,
- clone de um córrego
- reabrir um córrego depois de ter sido fechado
Solução 4
Graças a vários que sugeridas ToArray, fui levado a resposta certa, que é `M.GetBuffer'. ToArray não é tão ruim, mas
- faz uma cópia
- recebe apenas parte do buffer
GetBuffer apenas agarra uma referência para o byte subjacente [], que é o que eu sou depois.
Outras dicas
Você deve melhor obter o byte subjacente [] buffer usando
byte[] buffer = ms.GetBuffer();
E, em seguida, copiar os dados de bytes usando o método Array.Copy (). Você é livre para criar um novo fluxo com ele.
Você pode usar coisas como a MiscUtil.IO.NonClosingStreamWrapper
em MiscUtil , que envolve um Stream
e simplesmente ignora pedidos Close
/ Dispose
. Apenas para este fim.
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
}
Você pode:
- Chamada M.ToArray () para obter o fluxo como um array de bytes.
- subclasse BinaryWriter e substituir o método Dispose para evitar o fechamento do fluxo de criança
Apenas para adicioná-lo aqui, uma solução muito simples seria não para Dispose () o escritor.
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
}
Agora você só tem que se preocupar em manter B em escopo, que será durante R ().
Esta pode não ser a melhor solução aqui, mas vale a pena notar que os leitores e escritores não precisa Eliminação si mesmos.
A abordagem um tanto ingênuo é usar
byte buf[] = MemoryStream.ToArray();
Para copiar o conteúdo de fluxo para um array de bytes. Você pode ligá-lo novamente em um fluxo com
MemoryStream ms = new MemoryStream(buf);
Accoring para este M.Clone (); Deveria trabalhar. Mas eu posso estar errado ...