2010-02-10 84 views
40

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

我目前做的:

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

回答

62

不要使用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(...); 
} 
+6

这是不可行的,如果他需要使用字符串的东西之前,写它虽然。 – Skurmedel 2010-02-10 11:43:54

+10

绝对是真的,但他当然没有说这是一个要求,所以我没有做出任何假设。 – 2010-02-10 11:46:55

12

这是最好的方法。其他明智损失的StringBuilder和使用类似以下内容:

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

根据您的使用情况下,它也可能是有意义的只是一个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

非常确定:https://msdn.microsoft.com/en-us/library/system.io.stringwriter.getstringbuilder(v=vs.110).aspx – 2015-03-03 23:37:36

4

也许这将是有用的。

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 
+2

先复制到一个字符串,然后再复制到一个字节数组,那么最后复制到流?真?毫无疑问,这可以在不做任何中间拷贝的情况下简洁地完成。 (如果字符串生成器是2GB,会怎么样?) – 2017-02-15 10:52:17

0

如果你想使用类似StringBuilder的,因为它是清洁剂绕过而努力,那么你可以使用像我创建了下面的StringBuilder替代。

它所做的最重要的不同之处在于,它允许访问内部数据,而无需首先将其组装成字符串或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); 
    }); 
}