2013-06-28 6 views
2

У меня есть куча данных в MemoryStream, и я хочу написать все это до BinaryWriter.Скопировать данные из MemoryStream непосредственно в BinaryWriter.BaseStream?

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

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

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

+0

Согласно http://msdn.microsoft.com/en-us/library/dd782932.aspx, «Копирование начинается с текущей позиции в течении поток." – Gray

+0

@Gray Это _reading position_ является потоком _source_ прямо? Думаю, это не имеет никакого отношения к позиции BinaryWriter. – Virtlink

+0

Я просто размышляю здесь, не дай мне привести тебя. Я наткнулся на это: http://stackoverflow.com/questions/16341653/filestream-copytonet-connectstream-what-happens-intern, который, кажется, объясняет его реальную реализацию. – Gray

ответ

2

Если вы не хотите возиться с вами данных в исходном потоке будет не что-то вроде этой работы:

 var myStreamInitially = new MemoryStream(); 
     var myStreamClone = new MemoryStream(); 

     myStreamInitially.CopyTo(myStreamClone); 

     var binaryWriteb = new BinaryWriter(myStreamClone); 

Если вы используете .NET 4+ метод CopyTo очень удобно ,

UPDATE

Разве это не то безопаснее, чем изменение binaryStream, лежащий в основе BaseStream:

void WriteToStreamInUnknownStatus(BinaryWriter binaryWriter) 
    { 
     var myStream = new MemoryStream(); 

     try 
     { 
      binaryWriter.Write(myStream.ToArray()); 
     } 
     catch 
     { } 
    } 

UPDATE 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; 
    } 

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

+0

Ну, я получаю 'BinaryWriter' как входной сигнал метода. Этот писатель, возможно, писал вещи, прежде чем я его получил, и он может написать что-то после того, как я закончил. Поэтому мне действительно нужно использовать _that_ 'BinaryWriter' (или его базовый поток) и не может создать новый. – Virtlink

+0

@Virtlink Если это так, и вы не знаете, что такое состояние бинарной записи, почему вы не можете просто написать содержимое потока памяти, используя свои методы записи? – Marco

+0

Я уверен, но это проще, если это безопасно. – Virtlink

2

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

  1. Что вы используете это в однопоточных контексте. Либо нет других потоков, либо у вас есть исключительная блокировка для писателя в то время, когда вы это называете. ... И
  2. Вы звоните Flush на писателя, прежде чем писать непосредственно на BaseStream. У писателя могут быть некоторые буферизированные данные, которые он еще не написал в поток.

Таким образом, ваш модифицированный код:

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