Scrivi StringBuilder per lo streaming

Qual è il miglior metodo per scrivere uno StringBuilder su un System.IO.Stream?

Attualmente sto facendo:

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

Non usare StringBuilder, se stai scrivendo su uno stream, fallo con 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(...); } 

Questo è il metodo migliore. Altre saggi perdono lo StringBuilder e usano qualcosa come il seguente:

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

A seconda del tuo caso d’uso, potrebbe anche avere senso iniziare con 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 

Forse sarà 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 

Se vuoi usare qualcosa come StringBuilder perché è più semplice passare e lavorare, allora puoi usare qualcosa come il seguente sostituto di StringBuilder che ho creato.

La cosa più importante è che consente di accedere ai dati interni senza doverli assemblare prima in una stringa o in un ByteArray. Ciò significa che non è necessario raddoppiare i requisiti di memoria e rischiare di tentare di allocare un blocco contiguo di memoria che si adatta all’intero object.

NOTA: Sono sicuro che ci sono opzioni migliori usando una List() internamente, ma questo è stato semplice e si è rivelato abbastanza buono per i miei scopi.

 public class StringBuilderEx { List data = new List(); public void Append(string input) { data.Add(input); } public void AppendLine(string input) { data.Add(input + "\n"); } public void AppendLine() { data.Add("\n"); } ///  /// Copies all data to a String. /// Warning: Will fail with an OutOfMemoryException if the data is too /// large to fit into a single contiguous string. ///  public override string ToString() { return String.Join("", data); } ///  /// Process Each section of the data in place. This avoids the /// memory pressure of exporting everything to another contiguous /// block of memory before processing. ///  public void ForEach(Action processData) { foreach (string item in data) processData(item); } } 

Ora puoi scaricare l’intero contenuto in un file usando il seguente codice.

 var stringData = new StringBuilderEx(); stringData.Append("Add lots of data"); using (StreamWriter file = new System.IO.StreamWriter(localFilename)) { stringData.ForEach((data) => { file.Write(data); }); }