63 votes

Ecriture d'un StringBuilder dans un Stream

Quelle est la meilleure méthode pour écrire un StringBuilder dans un System.IO.Stream ?

Je suis en train de le faire :

StringBuilder message = new StringBuilder("All your base");
message.Append(" are belong to us");

System.IO.MemoryStream stream = new System.IO.MemoryStream();
System.Text.ASCIIEncoding encoding = new ASCIIEncoding();
stream.Write(encoder.GetBytes(message.ToString()), 0, message.Length);

99voto

Neil Barnwell Points 20731

N'utilisez pas de StringBuilder, si vous écrivez dans un flux, faites-le avec un fichier de type StreamWriter :

using (var memoryStream = new MemoryStream())
using (var writer = new StreamWriter(memoryStream ))
{
    // Various for loops etc as necessary that will ultimately do this:
    writer.Write(...);
}

12 votes

Ce n'est pas faisable s'il doit utiliser la chaîne pour autre chose avant de l'écrire.

11 votes

C'est tout à fait vrai, mais bien sûr il n'a pas dit que c'était une exigence, donc je n'ai pas fait de suppositions.

3 votes

N'oubliez pas non plus de La chasse d'eau et la recherche avant de lire le flux.

18voto

affan Points 1695

C'est la meilleure méthode. Sinon, vous pouvez perdre le StringBuilder et utiliser quelque chose comme ceci :

using (MemoryStream ms = new MemoryStream())
{
    using (StreamWriter sw = new StreamWriter(ms, Encoding.Unicode))
    {
        sw.WriteLine("dirty world.");
    }
    //do somthing with ms
}

8voto

Jabbersii Points 75

EDIT : Comme le fait remarquer @ramon-smits, si vous avez accès à StringBuilder.GetChunks() Vous aurez également accès à StreamWriter.WriteAsync(StringBuilder) . Vous pouvez donc faire ceci à la place :

StringBuilder stringBuilder = new StringBuilder();
// Write data to StringBuilder...
Stream stream = GetStream(); // Get output stream from somewhere.
using (var streamWriter = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true))
{
    await streamWriter.WriteAsync(stringBuilder);
}

Beaucoup plus simple.


J'ai récemment dû faire exactement la même chose et j'ai trouvé cette question avec des réponses insatisfaisantes.

Vous pouvez écrire un StringBuilder dans un Stream sans matérialiser la chaîne entière :

StringBuilder stringBuilder = new StringBuilder();
// Write data to StringBuilder...
Stream stream = GetStream(); // Get output stream from somewhere.
using (var streamWriter = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true))
{
    foreach (ReadOnlyMemory<char> chunk in stringBuilder.GetChunks())
    {
        await streamWriter.WriteAsync(chunk);
    }
}

N.B. Cette API (StringBuilder.GetChunks()) n'est disponible qu'en .NET Core 3.0 et plus.

Si cette opération est fréquente, vous pouvez encore réduire la pression de la GC en utilisant un pool d'objets StringBuilder.

7voto

Clark Kent Points 5845

Peut-être cela sera-t-il utile.

var sb= new StringBuilder("All your money");
sb.Append(" are belong to us, dude.");
var myString = sb.ToString();
var myByteArray = System.Text.Encoding.UTF8.GetBytes(myString);
var ms = new MemoryStream(myByteArray);
// Do what you need with MemoryStream

6voto

Chris Moschini Points 7278

En fonction de votre cas d'utilisation, il peut également être judicieux de commencer par un StringWriter :

StringBuilder sb = null;

// StringWriter - a TextWriter backed by a StringBuilder
using (var writer = new StringWriter())
{
    writer.WriteLine("Blah");
    . . .
    sb = writer.GetStringBuilder(); // Get the backing StringBuilder out
}

// Do whatever you want with the StringBuilder

1 votes

Tout à fait sûr : msdn.microsoft.com/fr/us/library/

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