2010-08-03 83 views
26

我最近讀到StringWriterStringReader用於寫入和從StringBuilder讀取。StringBuilder Vs StringWriter/StringReader

那麼當我使用StringBuilder對象時,它看起來是一個自給自足的類。

我們閱讀各種方式​​和寫作StringBuilder,使用 StringBuilder.Append()Insert()Replace()Remove()等等

  1. 什麼是可能使用的StringWriterStringReader,不能由StringBuilder完成本身?
  2. 它們的實際用途是什麼?
  3. 什麼可能是他們沒有把Stream作爲輸入(因爲任何其他作者和讀者都把這個流作爲Constructor參數來操作),但StringBuilder
+1

[StringWriter的或StringBuilder的]的可能的複製(http://stackoverflow.com/questions/602279/stringwriter-or-stringbuilder) – 2016-07-04 11:52:03

回答

31

StringWriter和StringReader的可能用途是什麼?這不能由StringBuilder本身完成嗎?

StringReaderStringWriter從分別TextReaderTextWriter派生。因此,他們可以做的是作爲TextReaderTextWriter實例,其中stringStringBuilder不能這樣做,因爲它們不會導出這兩種類型之一。

它們的實際用途是什麼?

它們允許你調用期待一個TextReaderTextWriter的API,當你有/要的是stringStringBuilder

可能是什麼,他們不佔用流作爲輸入(因爲任何其他作者和讀者正在服用的流作爲構造函數的參數進行操作),但StringBuilder的可能的原因是什麼?

因爲它們不適用於流;他們在string s或StringBuilder s上工作。它們只是簡單的包裝類,它們適用於期望不同界面的API的這些類型。參見:adapter pattern

1

我不確定是誰告訴你他們的目的是用於StringBuilder,但這是絕對不正確的。正如你所說的,StringBuilder可以在不使用其他類的情況下讀取和寫入。 StringWriter和StringReader類擴展了TextReader和TextWriter .Net Framework基類,並提供了用於處理文本數據的類流特性。例如,如果您需要使用某些XmlDocument類型的類,則某些方法允許您通過TextReader加載Xml數據,因此如果您將Xml文本作爲字符串變量加載,則可以將其加載到StringReader中然後將其提供給XmlDocument。

+0

你好,謝謝你的回答。我同意從TextWriter/TextReader派生出來的觀點。 我已經採取StringWriter爲例,並發現以下兩個初始化不起作用。 FileStream fs = new FileStream(@「C:\ Users \ Saravanan \ Documents \ something.bin」,FileMode.OpenOrCreate); StringWriter sw1 = File.CreateText(@「C:\ Users \ Saravanan \ Documents \ something.bin」); StringWriter sw2 = new StringWriter(fs); 只需要Stringbuilder來編寫。 – SaravananArumugam 2010-08-03 00:46:24

+1

@Saravanandss - 如果你想讀/寫流,然後使用'StreamReader'和'StreamWriter' ......這就是他們在那裏。 'StringReader'和'StringWriter'不是用來處理文件的;它們被設計用於處理字符串。你爲什麼試圖使用它們? – 2010-08-03 00:51:17

5

其他人已經說過了,但這是因爲它們來源於TextReader/TextWriter,可以用來代替它們。首先,如果只將內容作爲字符串使用,則使用相同的方法輸出用於文件的行的方式會更有意義。如果你想要在內存中跨越多行的輸出,爲什麼還要記住用StringBuilder在每一行的末尾加上「\ r \ n」?如果您希望代碼在只使用「\ n」換行的系統上運行或格式化數據,該怎麼辦?

StringBuilder sb = new StringBuilder(); 
// will be invalid on systems that only use \n 
sb.AppendFormat("{0:yyyy-MM-dd HH:mm:ss} - Start\r\n", DateTime.Now); 
// still have to add an extra parameter 
sb.AppendFormat("The current time is {0:yyyy-MM-dd HH:mm:ss}{1}", DateTime.Now, 
    Environment.NewLine); 

StringWriter sw = new StringWriter(); 
// Don't have to worry about it, method name tells you there's a line break 
sw.WriteLine("{0:yyyy-MM-dd HH:mm:ss} - Start", DateTime.Now); 
// no extra parameters 
sw.WriteLine("The current time is {0:yyyy-MM-dd HH:mm:ss}", DateTime.Now); 

說你要處理的文件裏逐行,你可能會使用,而不是整個文件到一個StringBuilder和換行符拆分其加載到一個數組一個StreamReader,對不對?使用StringReader,您可以使用完全相同的方法(只要它採用通用的TextReader),方法是通過從TextBox或Web窗體的字符串中創建StringReader。

Linq2Sql DataContexts有一個Log屬性,您可以將它設置爲TextWriter,以便在執行查詢之前輸出查詢以準確查看正在運行的內容。您可以將其設置爲附加到文件的TextWriter,但您可以附加一個StringWriter並在測試時輸出網頁底部的內容...

1

您可以使用StringReader從一個文件讀取所有整數串。

private static void Main() 
{ 
    var str = @" 
       13 
       13 
       0 6 
       0 5 
       0 1 
       0 2 
       5 3 
       6 4 
       5 4 
       3 4 
       7 8 
       9 10 
       11 12 
       9 11 
       9 12"; 


    using (StandardInput input = new StandardInput(new StringReader(str))) 
    { 
     List<int> integers = new List<int>(); 
     int n; 
     while ((n = input.ReadInt32()) != -1) 
     { 
      integers.Add(n); 
     } 
    } 
} 

StandardInput類:

class StandardInput : IDisposable 
{ 
    private readonly TextReader reader; 

    public StandardInput(TextReader reader) 
    { 
     this.reader = reader; 
    } 

    public int ReadInt32() 
    { 
     while (!char.IsDigit((char)reader.Peek()) && reader.Peek() != -1) 
     { 
      reader.Read(); 
     } 
     var builder = new StringBuilder(); 
     while (char.IsDigit((char) reader.Peek())) 
      builder.Append((char) reader.Read()); 

     return builder.Length == 0 ? -1 : int.Parse(builder.ToString()); 
    } 

    public double ReadDouble() 
    { 
     while (!char.IsDigit((char)reader.Peek()) && reader.Peek() != '.' 
                && reader.Peek() != -1) 
     { 
      reader.Read(); 
     } 
     var builder = new StringBuilder(); 
     if (reader.Peek() == '.') 
      builder.Append((char) reader.Read()); 
     while (char.IsDigit((char)reader.Peek())) 
      builder.Append((char)reader.Read()); 
     if (reader.Peek() == '.' && !builder.ToString().Contains(".")) 
     { 
      builder.Append((char)reader.Read()); 
      while (char.IsDigit((char)reader.Peek())) 
       builder.Append((char)reader.Read()); 
     } 
     return builder.Length == 0 ? -1 : double.Parse(builder.ToString()); 
    } 

    public void Dispose() 
    { 
     reader.Dispose(); 
    } 
}