将StringBuilder写入Stream

And*_*ner 50 c# stringbuilder stream

将StringBuilder写入System.IO.Stream的最佳方法是什么?

我目前在做:

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);
Run Code Online (Sandbox Code Playgroud)

Nei*_*ell 78

不要使用StringBuilder,如果您正在写入流,请使用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(...);
}
Run Code Online (Sandbox Code Playgroud)

  • 绝对正确,但当然他没有说这是一个要求,所以我没有做出任何假设. (11认同)
  • 如果他在编写之前需要将字符串用于其他内容,那是不可行的. (8认同)
  • 还要记住在从流中读取之前要[Flush and Seek](/sf/ask/395709541/)。 (2认同)

par*_*cle 14

这是最好的方法.其他明智的损失StringBuilder并使用如下内容:

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


Jab*_*sii 7

编辑:正如 @ramon-smits 指出的,如果您有权访问StringBuilder.GetChunks(),您也将有权访问StreamWriter.WriteAsync(StringBuilder). 所以你可以这样做:

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);
}
Run Code Online (Sandbox Code Playgroud)

简单多了。


我最近不得不做这件事,发现这个问题的答案并不令人满意。

您可以将 StringBuilder 写入 Stream,而无需具体化整个字符串:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:此 API (StringBuilder.GetChunks()) 仅在 .NET Core 3.0 及更高版本中可用

如果这种操作频繁发生,可以通过使用StringBuilder对象池来进一步降低GC压力。


Dev*_*per 6

也许它会很有用.

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
Run Code Online (Sandbox Code Playgroud)

  • 首先复制到一个字符串,然后再次复制到一个字节数组,然后最终复制到流?真?当然,这可以简洁地完成而无需制作任何中间副本.(如果字符串生成器是2GB怎么办?) (3认同)

Chr*_*ini 5

根据您的使用情况,从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
Run Code Online (Sandbox Code Playgroud)