Моя основная проблема в том, что при using
вызове Dispose
a StreamWriter
он также устраняет BaseStream
(ту же проблему с Close
).
У меня есть обходной путь, но, как видите, он включает в себя копирование потока. Есть ли способ сделать это без копирования потока?
Цель этого - получить содержимое строки (изначально считанной из базы данных) в поток, чтобы поток мог быть прочитан сторонним компонентом.
NB : я не могу изменить сторонний компонент.
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;
}
Используется в качестве
public void Noddy()
{
System.IO.Stream myStream = CreateStream("The contents of this string are unimportant");
My3rdPartyComponent.ReadFromStream(myStream);
}
В идеале я ищу воображаемый метод BreakAssociationWithBaseStream
, например,
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;
}
Ответы:
Если вы используете .NET Framework 4.5 или более поздней версии , существует перегрузка StreamWriter, с помощью которой вы можете попросить, чтобы основной поток оставался открытым при закрытии модуля записи .
В более ранних версиях .NET Framework до 4.5
StreamWriter
предполагается , что он владеет потоком. Параметры:StreamWriter
; просто промойте его.Close
/,Dispose
но проксирует все остальное. У меня есть реализация этого в MiscUtil , если вы хотите получить ее оттуда.источник
leaveOpen
параметр послеStreamWriter
создания?Dispose
его потребует . Окончание метода не делает этого автоматически. Он может быть завершен позже, если в нем есть финализатор, но это не одно и то же - и все еще не ясно, какую опасность вы ожидаете. Если вы считаете, что возвращать aStreamWriter
из метода небезопасно, потому что он может быть автоматически удален сборщиком мусора, это не так.StreamWriter
нет финализатора - я бы не ожидал, что он появится именно по этой причине.В .NET 4.5 для этого появился новый метод!
http://msdn.microsoft.com/EN-US/library/gg712853(v=VS.110,d=hv.2).aspx
источник
bufferSize
это1024
. Подробности здесь .Просто не обращайтесь
Dispose
кStreamWriter
. Причина, по которой этот класс является одноразовым, заключается не в том, что он содержит неуправляемые ресурсы, а в том, чтобы разрешить удаление потока, который сам может содержать неуправляемые ресурсы. Если жизнь базового потока обрабатывается где-то еще, нет необходимости удалять писатель.источник
Flush
сделает работу, если он буферизует данные?Поток памяти имеет свойство ToArray, которое можно использовать, даже когда поток закрыт. To Array записывает содержимое потока в байтовый массив независимо от свойства Position. Вы можете создать новый поток на основе записанного вами потока.
источник
Stream.Position
может быть вызван после его удаления.Вам нужно создать потомка StreamWriter и переопределить его метод удаления, всегда передавая false параметру удаления, он заставит средство записи потока НЕ закрыться, StreamWriter просто вызывает dispose в методе close, поэтому нет необходимости переопределите его (конечно, вы можете добавить все конструкторы, если хотите, у меня только один):
источник
disposing
Флаг является частью вIDisposable
шаблоне . Постоянный переходfalse
кDispose(bool)
методу базового класса в основном сигнализирует о том,StreamWriter
что он вызывается из финализатора (что не так, когда вы вызываетеDispose()
явно), и, следовательно, не должен обращаться к каким-либо управляемым объектам. Вот почему он не удаляет основной поток. Однако способ, которым вы этого добились, - это взлом; было бы гораздо проще вообще не звонитьDispose
!OwnedStream
, который игнорируетDispose(bool)
иClose
).