преобразовать строку в поток памяти — поток памяти не может быть расширен?

#c# #memorystream

#c# #memorystream

Вопрос:

я пытался записать строку в поток памяти, но не удалось с сообщением об ошибке:

 Memory stream is not expandable.
  

строка кода, которая создает эту проблему:

 context.Response.Filter = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(myPage));
  

у кого-нибудь есть обходной путь / исправление для этого?

трассировка стека:

 [NotSupportedException: Memory stream is not expandable.]
   System.IO.MemoryStream.set_Capacity(Int32 value)  9385744
   System.IO.MemoryStream.EnsureCapacity(Int32 value)  50
   System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)  265
   System.Web.HttpWriter.FilterIntegrated(Boolean finalFiltering, IIS7WorkerRequest wr)  9155697
   System.Web.HttpResponse.FilterOutput()  159
   System.Web.CallFilterExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()  52
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Booleanamp; completedSynchronously)  75
  

Комментарии:

1. что такое `mypage’ непосредственно строка?

2. Что вы пытаетесь сделать? Из того, что я получил в документации, HttpResponse.Filter не предназначено для использования подобным образом.

3. @msarchet = да, это строка.

4. @EtiennedeMartel — если вы попытаетесь манипулировать ответом, это правильный путь. msdn.microsoft.com/en-us/library /…

5. Да, но если вы хотите вывести материал в ответ, почему бы просто не вызвать Write ? Что вы пытаетесь здесь сделать?

Ответ №1:

Следующий код работает корректно для меня

 public class Foo
{
    public static void Main()
    {
        var myPage = "test string";
        var repo =  new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(myPage));
    }
}
  

Кажется, что правильный способ сделать это — создать MemoryStream с использованием конструктора по умолчанию

 var repo = new System.IO.MemoryStream();
  

а затем записать в него

 var stringBytes = System.Text.Encoding.UTF8.GetBytes(myPage);
repo.Write(stringBytes, 0, stringBytes.Length);
  

если вы хотите иметь возможность читать поток как обычно (например, с помощью StreamReader), то вам также нужно будет вызвать:

 repo.Seek(0, SeekOrigin.Begin);
  

Ответ №2:

Пользовательский поток, который добавляет данные, был бы более подходящим.

Минимально протестировано. Предполагается, что вы хотите, чтобы текст записывался при сбросе потока, и то только один раз.

 public class AppendTextFilter : Stream
{
    private Stream Filter { get; set; }
    private string Text { get; set; }
    private bool TextWritten { get; set; }

    public AppendTextFilter( Stream filter, string text )
    {
        this.Filter = filter;
        this.Text = text;
    }

    public override bool CanRead { get { return Filter.CanRead; } }

    public override bool CanSeek { get { return Filter.CanSeek; } }

    public override bool CanWrite { get { return Filter.CanWrite; } }

    public override void Flush()
    {
        if (!TextWritten)
        {
            var bytes = Encoding.UTF7.GetBytes( Text );
            Filter.Write( bytes, 0, bytes.Length );
            TextWritten = true;
        }
        Filter.Flush();
    }

    public override long Length { get { return Filter.Length   Text.Length; } }

    public override long Position
    {
        get
        {
            return Filter.Position;
        }
        set
        {
            Filter.Position = value;
        }
    }

    public override int Read( byte[] buffer, int offset, int count )
    {
        return Filter.Read( buffer, offset, count );
    }

    public override long Seek( long offset, SeekOrigin origin )
    {
        return Filter.Seek( offset, origin );
    }

    public override void SetLength( long value )
    {
        Filter.SetLength( value );
    }

    public override void Write( byte[] buffer, int offset, int count )
    {
        Filter.Write( buffer, offset, count );
    }
}
  

Ответ №3:

Когда вы создаете MemoryStream из массива байтов, вы, по сути, создаете оболочку вокруг указанного массива. Это означает, что буфер потока не может расшириться, как только он достигнет своей емкости.

Однако, HttpResponse.Filter по сути, это фильтр. В документации говорится:

Когда вы создаете объект Stream и присваиваете свойству Filter значение Stream object, все выходные данные HTTP, отправляемые с помощью Write, проходят через фильтр.

Таким образом, данные в конечном итоге записываются в MemoryStream . Итак, было бы полезно узнать, чего именно вы пытаетесь достичь с помощью этого, потому что MemoryStream не создал бы полезный фильтр…

Комментарии:

1. я пытаюсь манипулировать ответом, добавил некоторый текст на страницу. вот и все.

Ответ №4:

             byte[] buffer = File.ReadAllBytes("test.xml");
            XmlDocument doc = new XmlDocument();
            using (MemoryStream output = new MemoryStream())
            {
                using (MemoryStream ms = new MemoryStream(buffer ))
                {
                    doc.Load(ms);
                }
                // Make changes to your memory stream here
                doc.Save(output);//Output stream has the changes.
            }