Moim głównym problemem jest to, że kiedy using
wywołuje Dispose
a StreamWriter
, usuwa również BaseStream
(ten sam problem z Close
).
Mam obejście tego problemu, ale jak widzisz, wymaga to skopiowania strumienia. Czy można to zrobić bez kopiowania strumienia?
Ma to na celu pobranie zawartości ciągu (pierwotnie odczytanego z bazy danych) do strumienia, aby strumień mógł zostać odczytany przez komponent innej firmy.
Uwaga : nie mogę zmienić komponentu innej firmy.
public System.IO.Stream CreateStream(string value)
{
var baseStream = new System.IO.MemoryStream();
var baseCopy = new System.IO.MemoryStream();
using (var writer = new System.IO.StreamWriter(baseStream, System.Text.Encoding.UTF8))
{
writer.Write(value);
writer.Flush();
baseStream.WriteTo(baseCopy);
}
baseCopy.Seek(0, System.IO.SeekOrigin.Begin);
return baseCopy;
}
Użyty jako
public void Noddy()
{
System.IO.Stream myStream = CreateStream("The contents of this string are unimportant");
My3rdPartyComponent.ReadFromStream(myStream);
}
Idealnie szukam wyimaginowanej metody o nazwie BreakAssociationWithBaseStream
np
public System.IO.Stream CreateStream_Alternate(string value)
{
var baseStream = new System.IO.MemoryStream();
using (var writer = new System.IO.StreamWriter(baseStream, System.Text.Encoding.UTF8))
{
writer.Write(value);
writer.Flush();
writer.BreakAssociationWithBaseStream();
}
return baseStream;
}
Odpowiedzi:
Jeśli używasz .NET Framework 4.5 lub nowszego, istnieje przeciążenie StreamWriter, za pomocą którego możesz poprosić o pozostawienie otwartego strumienia podstawowego, gdy moduł zapisujący jest zamknięty .
We wcześniejszych wersjach .NET Framework starszych niż 4.5
StreamWriter
zakłada, że jest właścicielem strumienia. Opcje:StreamWriter
; po prostu spłucz to.Close
/,Dispose
ale wszystkie inne serwery proxy. Mam implementację tego w MiscUtil , jeśli chcesz ją stamtąd pobrać.źródło
leaveOpen
parametru poStreamWriter
utworzeniu?Dispose
. Zakończenie metody nie robi tego automatycznie. Może zostać sfinalizowany później, jeśli ma finalizator, ale to nie to samo - i nadal nie jest jasne, jakiego niebezpieczeństwa się spodziewasz. Jeśli uważasz, że zwrócenieStreamWriter
metody z metody jest niebezpieczne, ponieważ może zostać automatycznie usunięte przez GC, to po prostu nieprawda.StreamWriter
nie ma finalizatora - nie spodziewałbym się tego właśnie z tego powodu..NET 4.5 ma nową metodę dla tego!
http://msdn.microsoft.com/EN-US/library/gg712853(v=VS.110,d=hv.2).aspx
źródło
bufferSize
to1024
. Szczegóły tutaj .Proszę nie dzwonić
Dispose
poStreamWriter
. Powodem, dla którego ta klasa jest dostępna, nie jest to, że zawiera niezarządzane zasoby, ale umożliwia pozbycie się strumienia, który sam może zawierać niezarządzane zasoby. Jeśli żywotność podstawowego strumienia jest obsługiwana w innym miejscu, nie ma potrzeby usuwania osoby zapisującej.źródło
Flush
buforowało dane?Strumień pamięci ma właściwość ToArray, której można używać nawet wtedy, gdy strumień jest zamknięty. To Array zapisuje zawartość strumienia do tablicy bajtów, niezależnie od właściwości Position. Możesz utworzyć nowy strumień na podstawie strumienia, w którym napisałeś.
źródło
Stream.Position
może nie być nazywane po jej wyrzucać.Musisz utworzyć element podrzędny StreamWriter i nadpisać jego metodę dispose, zawsze przekazując false do parametru disposing, wymusi to NIE zamykanie modułu zapisującego strumień, StreamWriter po prostu wywołuje dispose w metodzie close, więc nie ma potrzeby nadpisać (oczywiście możesz dodać wszystkie konstruktory, jeśli chcesz, mam tylko jeden):
źródło
disposing
Flaga jest częścią tejIDisposable
strukturze . Zawsze przekazywaniefalse
doDispose(bool)
metody klasy bazowej zasadniczo sygnalizujeStreamWriter
, że jest ona wywoływana z finalizatora (co nie jest tak, gdy wywołujeszDispose()
jawnie), a zatem nie powinno uzyskiwać dostępu do żadnych zarządzanych obiektów. To dlatego, że nie będzie wyrzucać strumienia bazowego. Jednak sposób, w jaki to osiągnąłeś, to hack; byłoby o wiele prościej po prostu nie dzwonićDispose
!OwnedStream
, która ignorujeDispose(bool)
iClose
).