将字符串转换为内存流-内存流不可扩展
本文关键字:内存 可扩展 字符串 转换 | 更新日期: 2023-09-27 18:14:06
我试图将字符串写入内存流,但是失败了,显示错误信息:
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, Boolean& completedSynchronously) +75
下面的代码可以正常运行
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);
添加数据的自定义流更合适。
最小测试。假设您希望在刷新流时写入文本,然后只写入一次。
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 );
}
}
从字节数组创建MemoryStream
时,实际上是在该数组周围创建了一个包装器。这意味着流的缓冲区一旦达到容量就无法扩展。
然而,HttpResponse.Filter
本质上是:过滤器。文档说明:
当你创建一个Stream对象并将Filter属性设置为Stream对象时,Write发送的所有HTTP输出都将通过该过滤器。
因此数据最终被写入MemoryStream
。所以它会帮助你知道你想要实现什么,确切地说,因为MemoryStream
不会成为一个有用的过滤器。
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.
}