EDIT: As @ramon-smits points out, if you have access to StringBuilder.GetChunks()
, you will also have access to StreamWriter.WriteAsync(StringBuilder)
. So you can just do this instead:
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);
}
Much simpler.
I recently had to do exactly this thing and found this question with unsatisfactory answers.
You can write a StringBuilder to a Stream without materializing the entire string:
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. This API (StringBuilder.GetChunks()) is only available in .NET Core 3.0 and above
If this operation happens frequently, you could further reduce GC pressure by using a StringBuilder object pool.