27 votes

convertir la chaîne en flux mémoire - Le flux mémoire n'est pas extensible?

j'essayais d'écrire une chaîne dans un flux de mémoire, mais j'ai échoué avec le message d'erreur:

 Memory stream is not expandable.
 

la ligne de code qui produit ce problème:

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

quelqu'un a une solution de contournement / correctif pour cela?

trace de la pile:

 [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
 

61voto

msarchet Points 9059

Le code suivant fonctionne correctement pour moi

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

Il semble que la bonne façon de procéder consiste à créer le MemoryStream à l'aide du constructeur par défaut

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

puis y écrire

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

si vous voulez pouvoir lire le flux normalement (par exemple en utilisant un StreamReader), vous devrez également appeler:

 repo.Seek(0, SeekOrigin.Begin);
 

3voto

Etienne de Martel Points 16020

Lorsque vous créez un MemoryStream à partir d'un tableau d'octets, vous avez essentiellement de créer un wrapper autour de ladite matrice. Ce qui signifie que le flux de la mémoire tampon ne peut pas développer une fois qu'il a atteint sa capacité.

Cependant, une HttpResponse.Filter est, en substance, que: un filtre. La documentation indique:

Lorsque vous créez un objet de Flux de données et de configurer le Filtre de la propriété de l'objet de Flux de données, tous HTTP sortie est envoyée par l'Écriture passe par le filtre.

De sorte que les données finit par être écrit à l' MemoryStream. Donc, il serait utile de savoir ce que vous essayez d'atteindre avec ce, exactement, parce qu'un MemoryStream ne ferait pas un filtre utile...

2voto

tvanfosson Points 268301

Un flux personnalisé qui ajoute les données serait plus approprié.

Peu testé. Suppose que vous voulez que le texte soit écrit lorsque le flux est vidé, puis une seule fois.

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

1voto

sowmzs Points 21
            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.
            }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X