2009-10-27 7 views
8

Jako discussed before, gdy BinaryReader lub BinaryWriter zostanie zamknięty, jego Strumień bazowy również zostanie zamknięty (aargh). Rozważmy tę sytuację: procedura R jest przekazywana do obiektu MemoryStream, na przykład M; Chciałbym napisać kilka rzeczy do M, a następnie przekazać je do innej procedury w celu dalszego przetwarzania (niekoniecznie w formie pisemnej). Dla wygody chciałbym zawinąć M w BinaryWriter, aby zrobić moje pisanie. Po napisaniu, skończyłem z BinaryWriter, ale nie z M.Jak mogę "rozwidlić" strumień w .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 
} 

Ale nie mogę wyrzucać BinaryStream bez zamykania M.

P: Czy można wykonać jedną z poniższych czynności?

  • wyodrębnić podstawowe bajt [] Z MemoryStream,
  • klon Strumień
  • ponownie otworzyć strumień po jego zamknięciu
+0

Nie wiem, C#, ale w Javie po prostu po prostu porzucić bez zamykania BinaryWriter. Czy użycie siły konstrukcyjnej {...} nie jest zamykane? Więc nie używaj tego konstruktu! –

+0

P.S. Ale musisz upewnić się, że opróżniasz BinaryWriter zanim go porzucisz. –

Odpowiedz

2

Dzięki kilku, którzy zasugerowali ToArray, zostałem doprowadzony do właściwej odpowiedzi, którą jest "M.GetBuffer". ToArray nie jest tak źle, ale

  • tworzy kopię
  • dostaje tylko część bufora

GetBuffer prostu chwyta odniesienie do podstawowej byte [], która jest co jestem po.

+0

, co zostało wskazane w mojej odpowiedzi ;) –

0

nieco naiwne podejściem jest użycie

byte buf[] = MemoryStream.ToArray(); 

Aby skopiować zawartość strumienia do tablicy bajtów. Można włączyć go z powrotem do strumienia z

MemoryStream ms = new MemoryStream(buf); 
+0

Warto podkreślić: ta metoda działa zarówno w strumieniu zamkniętym, jak i na żywo. –

2

można:

  • połączeń M.ToArray(), aby uzyskać strumień jako tablica bajtów.
  • podklasa BinaryWriter i zastąpić metodę przekazać do zapobiegania zamykania strumienia dzieci
+0

+1 specjalnie dla trybu nadpisania. –

+0

Nie możesz po prostu unikać nawiązywania/zamykania? –

-1

Accoring do this M.Clone(); powinno działać. Ale mogę się mylić ...

+0

-1 za opublikowanie na stronie internetowej, która nie zezwala na oglądanie jej zawartości za darmo, co jest praktycznie bezużyteczne. –

7

Powinieneś lepiej dostać [] bufor bazowy bajtów używając

byte[] buffer = ms.GetBuffer(); 

i skopiuj bajt danych za pomocą metody Array.Copy(). Możesz z niego utworzyć nowy strumień.

+0

Nie rozumiem, dlaczego mówisz, że lepiej jest użyć GetBuffer, a następnie zrobić kopię za pomocą Array.Copy. Gdybym chciał kopię, użyłbym ToArray. –

+0

Od MSDN doc Ta metoda pomija nieużywane bajty w MemoryStream z tablicy. Aby uzyskać cały bufor, użyj metody GetBuffer. http://msdn.microsoft.com/en-us/library/system.io.memorystream.toarray.aspx –

+0

Powyższa "Ta metoda" odnosi się do MemoryStream.ToArray() –

5

Można używać rzeczy jak MiscUtil.IO.NonClosingStreamWrapper w MiscUtil, która owija się Stream i po prostu ignoruje Close/Dispose żądań. Tylko w tym celu.

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

Wystarczy dodać go tutaj, to bardzo proste rozwiązanie byłoby nie Dispose() pisarza.

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 
} 

Teraz trzeba tylko martwić się o zachowanie B w zakresie, który będzie podczas R().

To może nie być najlepsze rozwiązanie, ale warto zauważyć, że Czytelnicy i Pisarze nie potrzebują Pozbywania się.

+0

Miejmy nadzieję, że 'BinaryWriter' niczego nie buforuje, to ... –

+0

Ale upewnij się, że wywołasz B.flush() po tym, jak skończyłeś z nim na wypadek, gdyby nie przepchnął wszystkiego do M. (To jest co byłoby potrzebne w Javie, nie ma pojęcia o C#) –

+0

OK, Adrian i Marc, zapomniałem Flush(). –