2010-02-10 62 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); 
    }); 
}