crear - memorystream to stream c#
Convierta una cadena en una secuencia de memoria. ¿La secuencia de memoria no se puede expandir? (4)
Estaba tratando de escribir una cadena en una secuencia de memoria, pero falló con el mensaje de error:
Memory stream is not expandable.
la línea de código que produce este problema:
context.Response.Filter = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(myPage));
Alguien tiene una solución / solución para eso?
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
Cuando crea un MemoryStream
partir de una matriz de bytes, básicamente crea un contenedor alrededor de dicha matriz. Lo que significa que el búfer de la secuencia no puede expandirse una vez que alcanza su capacidad.
Sin embargo, un HttpResponse.Filter
es esencialmente eso: un filtro . La documentación dice:
Cuando crea un objeto Stream y establece la propiedad Filter en el objeto Stream, todos los resultados HTTP enviados por Write pasan por el filtro.
Así que los datos se escriben en el MemoryStream
. Por lo tanto, sería útil saber exactamente qué intenta lograr con esto, porque un MemoryStream
no sería un filtro útil ...
El siguiente código funciona correctamente para mí
public class Foo
{
public static void Main()
{
var myPage = "test string";
var repo = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(myPage));
}
}
Parece que la forma correcta de hacerlo es crear el MemoryStream
usando el constructor predeterminado
var repo = new System.IO.MemoryStream();
y luego escribirle
var stringBytes = System.Text.Encoding.UTF8.GetBytes(myPage);
repo.Write(stringBytes, 0, stringBytes.Length);
si desea poder leer la transmisión de la forma habitual (por ejemplo, utilizando un StreamReader), también deberá llamar a:
repo.Seek(0, SeekOrigin.Begin);
Una secuencia personalizada que anexe los datos sería más apropiada.
Mínimamente probado. Se supone que desea que se escriba el texto cuando la corriente se vacía, y luego solo una vez.
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 );
}
}
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.
}