将StringBuilder写入Stream

时间:2010-02-10 11:34:29

标签: c# stream stringbuilder

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

6 个答案:

答案 0 :(得分:76)

如果您正在写一个流,请不要使用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(...);
}

答案 1 :(得分:14)

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

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

答案 2 :(得分: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

答案 3 :(得分: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

答案 4 :(得分:0)

如果你想使用类似StringBuilder的东西,因为传递和使用它更干净,那么你可以使用类似我创建的以下StringBuilder替代品。

它最重要的不同之处在于它允许访问内部数据而无需先将其组装成String或ByteArray。这意味着您不必将内存需求加倍,并且可能会尝试分配适合整个对象的连续内存块。

注意:我确信有更好的选择,然后在内部使用List<string>(),但这很简单,并且证明对我的目的来说足够好。

public class StringBuilderEx
{
    List<string> data = new List<string>();
    public void Append(string input)
    {
        data.Add(input);
    }
    public void AppendLine(string input)
    {
        data.Add(input + "\n");
    }
    public void AppendLine()
    {
        data.Add("\n");
    }

    /// <summary>
    /// 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.
    /// </summary>
    public override string ToString()
    {
        return String.Join("", data);
    }

    /// <summary>
    /// Process Each section of the data in place.   This avoids the
    /// memory pressure of exporting everything to another contiguous
    /// block of memory before processing.
    /// </summary>
    public void ForEach(Action<string> processData)
    {
        foreach (string item in data)
            processData(item);
    }
}

现在您可以使用以下代码将整个内容转储到文件中。

var stringData = new StringBuilderEx();
stringData.Append("Add lots of data");

using (StreamWriter file = new System.IO.StreamWriter(localFilename))
{
    stringData.ForEach((data) =>
    {
        file.Write(data);
    });
}

答案 5 :(得分:0)

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

您可以在不具体化整个字符串的情况下将StringBuilder写入Stream:

File "C:\Users\User\Desktop\tensor\network\untitled10.py", line 53, in <module>
    dbx.files_upload(f.read(), dest_path, mute=True)

  File "C:\Users\User\Anaconda3\envs\AI\lib\site-packages\dropbox\base.py", line 2964, in files_upload
    f,

  File "C:\Users\User\Anaconda3\envs\AI\lib\site-packages\dropbox\dropbox.py", line 338, in request
    user_message_locale)

ApiError: ApiError('56376ca00bfc465b8a0a6c55a626a583', UploadError('path', UploadWriteFailed(reason=WriteError('malformed_path', None), upload_session_id='AAAAAAAAAId17KDB4XpN4g')))

N.B。此API(StringBuilder.GetChunks())仅在.NET Core 3.0及更高版本中可用

如果此操作频繁发生,则可以使用StringBuilder对象池进一步降低GC压力。