2009-10-27 2 views
8

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

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,
  • клона поток
  • повторно открыть поток после того, как он был закрыт
+0

Я не знаю C#, но на Java вы просто просто отказываетесь, не закрывая BinaryWriter. Не закрывается ли использование конструкции {...}? Тогда не используйте эту конструкцию! –

+0

P.S. Но вам нужно убедиться, что вы очистите BinaryWriter, прежде чем покинуть его. –

ответ

2

Благодаря нескольким, кто предложил ToArray, я получил правильный ответ, который является «M.GetBuffer». ToArray не так уж плохо, но это

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

GetBuffer просто захватывает ссылку на базовый байт [], что и я после.

+0

Что было указано в моем ответе ;) –

0

несколько наивного подход заключается в использовании

byte buf[] = MemoryStream.ToArray(); 

Чтобы скопировать содержимое потока в массив байтов. Вы можете превратить его обратно в поток с

MemoryStream ms = new MemoryStream(buf); 
+0

Стоит подчеркнуть: этот метод работает как с закрытым потоком, так и с живым. –

2

Вы можете:

  • вызова M.ToArray(), чтобы получить поток в виде массива байтов.
  • Подкласс BinaryWriter и переопределить метод Dispose, чтобы предотвратить закрытие дочернего потока
+0

+1 специально для параметра Dispose override. –

+0

Не могли бы вы просто не позвонить по телефону close/Dispose? –

-1

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

+0

-1 для публикации на веб-сайте, который не позволяет просматривать его содержимое бесплатно, что почти бесполезно –

7

Вы должны лучше получить базовые байты [] буфер с помощью

byte[] buffer = ms.GetBuffer(); 

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

+0

Не понимаю, почему вы говорите, что лучше использовать GetBuffer, а затем сделать копию с помощью Array.Copy. Если бы я хотел получить копию, я бы просто использовал ToArray. –

+0

От MSDN doc Этот метод исключает неиспользуемые байты в MemoryStream из массива. Чтобы получить весь буфер, используйте метод GetBuffer. http://msdn.microor.com/en-us/library/system.io.memorystream.toarray.aspx –

+0

Вышеупомянутый «Этот метод» относится к MemoryStream.ToArray() –

5

Вы можете использовать такие вещи, как 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 
}  
1

Просто, чтобы добавить его здесь, очень простое решение было бы не в 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

Надеемся, что 'BinaryWriter' ничего не забудет, а затем ... –

+0

Но убедитесь, что вы вызвали B.flush() после того, как вы закончили с ним, если он не протащил все до M. (Это что понадобится на Java, не знаю о C#) –

+0

OK, Adrian & Marc, я забыл Flush(). –

Смежные вопросы