Скопировать данные из MemoryStream напрямую в BinaryWriter.BaseStream?
У меня есть куча данных в MemoryStream
и я хочу написать все это BinaryWriter
,
К счастью для меня все потоки теперь есть Stream.CopyTo(Stream)
метод, и я могу получить целевой поток из BinaryWriter.BaseStream
собственность
public void WriteTo(BinaryWriter writer)
{
this.memoryStream.CopyTo(writer.BaseStream);
}
Могу ли я безопасно обойти писателя таким образом и скопировать его непосредственно в базовый поток, или это испортит буфер писателя, положение или что-то еще? Или, как бы вы предложили скопировать Stream
к BinaryWriter
?
2 ответа
То, что вы предлагаете, безопасно, при условии:
- То, что вы используете это в однопоточном контексте. Либо нет других потоков, либо у вас есть эксклюзивная блокировка на устройстве записи в тот момент, когда вы вызываете это.... А ТАКЖЕ
- Ты звонишь
Flush
на писателя, прежде чем писать непосредственно вBaseStream
, Автор может иметь некоторые данные в буфере, которые еще не записаны в поток.
Итак, ваш модифицированный код:
public void WriteTo(BinaryWriter writer)
{
writer.Flush();
this.memoryStream.CopyTo(writer.BaseStream);
}
Если вы не хотите связываться с данными, которые у вас есть в начальном потоке, это не сработает:
var myStreamInitially = new MemoryStream();
var myStreamClone = new MemoryStream();
myStreamInitially.CopyTo(myStreamClone);
var binaryWriteb = new BinaryWriter(myStreamClone);
Если вы используете.NET 4+, метод CopyTo очень удобен.
ОБНОВИТЬ
Разве это не безопаснее, чем изменение binaryStream, лежащего в основе baseStream:
void WriteToStreamInUnknownStatus(BinaryWriter binaryWriter)
{
var myStream = new MemoryStream();
try
{
binaryWriter.Write(myStream.ToArray());
}
catch
{ }
}
ОБНОВЛЕНИЕ 2
Если вы попробуете это, вы получите исключение: "поток памяти не расширяется"
static void Main(string[] args)
{
var binaryWrite = new BinaryWriter(new MemoryStream(new byte[] {1, 2, 3, 4}));
binaryWrite.Seek(3, SeekOrigin.Begin);
var position = binaryWrite.BaseStream.Position;
new MemoryStream(new byte[] {1, 2, 3, 4}).CopyTo(binaryWrite.BaseStream);
position = binaryWrite.BaseStream.Position;
}
Таким образом, чтобы быть уверенным в том, что свойство является потокобезопасным, вам также необходимо знать тип внутреннего потока. Рисковать ИМО.