Скопировать данные из MemoryStream напрямую в BinaryWriter.BaseStream?

У меня есть куча данных в MemoryStream и я хочу написать все это BinaryWriter,

К счастью для меня все потоки теперь есть Stream.CopyTo(Stream) метод, и я могу получить целевой поток из BinaryWriter.BaseStream собственность

public void WriteTo(BinaryWriter writer)
{
    this.memoryStream.CopyTo(writer.BaseStream);
}

Могу ли я безопасно обойти писателя таким образом и скопировать его непосредственно в базовый поток, или это испортит буфер писателя, положение или что-то еще? Или, как бы вы предложили скопировать Stream к BinaryWriter?

2 ответа

То, что вы предлагаете, безопасно, при условии:

  1. То, что вы используете это в однопоточном контексте. Либо нет других потоков, либо у вас есть эксклюзивная блокировка на устройстве записи в тот момент, когда вы вызываете это.... А ТАКЖЕ
  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;
    }

Таким образом, чтобы быть уверенным в том, что свойство является потокобезопасным, вам также необходимо знать тип внутреннего потока. Рисковать ИМО.

Другие вопросы по тегам