Как я могу клонировать объект MemoryStream?

У меня есть объект MemoryStream, который передается параметром типа Stream
(Stream - абстрактный класс в С#).

Я хочу клонировать его и создать другой объект MemoryStream стороной с текущей позицией оригинала и создать из нее новый XMLReader, поэтому я смогу прочитать его содержимое.

Это то, что я сделал, и он не работает (отладка строки с //*newReader имеет значение {None})
Предположение: вы находитесь внутри метода и имеете ссылку Stream currentStream.

var x = new XmlReaderSettings();
x.IgnoreWhitespace = true;  

 using (var newMemoryStream = new MemoryStream())
 {
         stream.CopyTo(newMemoryStream);

         using (var newReader = XmlReader.Create(newMemoryStream,x)) //*
         {

           Doing some stuff...

         }
 }

Ответ 1

Я решил свою проблему!:)
Пропущенные вещи отмечены //*. Вот код, как и должно быть:

var xmlReaderSettings = new XmlReaderSettings();

stream.Position = 0;//*
xmlReaderSettings.IgnoreWhitespace = true;
using (var newMemoryStream = new MemoryStream())
{
    stream.CopyTo(newMemoryStream);
    newMemoryStream.Position = 0;  //*
    using (var newReader = XmlReader.Create(newMemoryStream, xmlReaderSettings))
    {
        newReader.MoveToContent(); //*

        Doing some stuff...
    }
}

Ответ 2

Убедитесь, что reset позиция на newMemoryStream выглядит так:

newMemoryStream.Position = 0;

после stream.CopyTo(newMemoryStream);, но перед созданием XmlReader

Итак, все должно выглядеть так:

var x = new XmlReaderSettings();
x.IgnoreWhitespace = true;  

using (var newMemoryStream = new MemoryStream())
{
    stream.CopyTo(newMemoryStream);
    newMemoryStream.Position = 0;

    using (var newReader = XmlReader.Create(newMemoryStream,x)) //*
    {
        Doing some stuff...
    }
}

Кроме того, поскольку вы используете другой ридер в исходном потоке перед тем, как вводить этот метод, убедитесь, что Position исходного потока действительно там, где вы хотите.

Ответ 3

Вы можете использовать следующий метод расширения для клонирования MemoryStream, включая его текущую позицию, и убедитесь, что позиция оригинала MemoryStream равна reset в исходное положение после клонирования:

public static MemoryStream Clone(this MemoryStream ms) {
    var pos = ms.Position;
    var ms2 = new MemoryStream();
    ms.CopyTo(ms2);
    ms.Position = pos;
    ms2.Position = pos;
    return ms2;
}