convert string to memory stream - Memory stream is not expandable?

寵の児 提交于 2019-12-20 17:34:42

问题


i was trying to write a string to a memory stream, but failed with the error message:

Memory stream is not expandable.

the line of code that produces this problem:

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

anyone have a workaround/fix for that?

stacktrace:

[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, Boolean& completedSynchronously) +75

回答1:


A custom stream that appends the data would be more appropriate.

Minimally tested. Assumes that you want the text written when the stream is flushed, and then only once.

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



回答2:


The following code works correctly for me

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

It seems that the correct way to do this is to create the MemoryStream using the default constructor

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

and then write to it

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

if you want to be able to read the stream as normal (eg using a StreamReader) then you will also need to call:

repo.Seek(0, SeekOrigin.Begin);



回答3:


When you create a MemoryStream from a byte array, you essentially create a wrapper around said array. Which means the stream's buffer cannot expand once it reaches its capacity.

However, an HttpResponse.Filter is essentially that: a filter. The documentation states:

When you create a Stream object and set the Filter property to the Stream object, all HTTP output sent by Write passes through the filter.

So data ends up being written to the MemoryStream. So it would help to know what you're trying to achieve with this, exactly, because a MemoryStream would not make a useful filter...




回答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.
            }


来源:https://stackoverflow.com/questions/8097152/convert-string-to-memory-stream-memory-stream-is-not-expandable

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!