2009-03-02 1 views

ответ

2

A StringWriter используется для ввода текста в память файл и StringBuilder используется для добавления строк вместе в памяти эффективным способом.

0

StringBuilder Используется для массового конкатенации строк. Это более эффективно для более чем 5 строк, насколько я знаю, тогда String.Concat(). Также он может быть использован с конкретным форматом (.AppendFormat())

+0

Ваш последний абзац применяется к String * Builder *, а не к StringWriter. –

+1

Хмм .. MSDN сказал, что «StringWriter Class реализует TextWriter для записи информации в строку» http://msdn.microsoft.com/en-us/library/system.io.stringwriter.aspx – abatishchev

3

StringBuilder классом является в основном изменяемыми строками, вспомогательным классом для конструкции непреложных строками. StringWriter построен сверху, чтобы добавить дополнительные функции удобства для форматирования строк.

54

StringWriter происходит от TextWriter, что позволяет различным классам писать текст, не заботясь о том, куда он идет. В случае StringWriter выход поступает в память. Вы использовали бы это, если вы вызываете API, которому требуется TextWriter, но вы хотите только наращивать результаты в памяти.

StringBuilder - это, по сути, буфер, который позволяет выполнять несколько операций (обычно прилагается) к «логической строке» без создания нового строкового объекта каждый раз. Вы должны использовать это для построения строки в нескольких операциях.

69

Я не думаю, что любой из существующих ответов действительно отвечает на вопрос. Фактическая взаимосвязь между двумя классами является примером the adaptor pattern.

StringWriter осуществляет все свои методы Write... путем пересылки на экземпляр StringBuilder, который он хранит в поле. Это не просто внутренняя деталь, потому что StringWriter имеет общедоступный метод GetStringBuilder, который возвращает внутренний построитель строк, а также a constructor, который позволяет вам пройти в существующем StringBuilder.

So StringWriter - это адаптер, который позволяет использовать StringBuilder в качестве цели кодом, который рассчитывает работать с TextWriter. С точки зрения базового поведения явно нет выбора между ними ... если вы не можете измерить накладные расходы на пересылку вызовов, и в этом случае StringWriter будет немного медленнее, но это кажется очень маловероятным.

Так почему же они не сделали StringBuilder орудием TextWriter? Это серая область, потому что намерение интерфейса не обязательно всегда ясно на первый взгляд.

TextWriterочень близко интерфейс к чему-то, что принимает поток символов. Но у него есть дополнительная морщина: свойство называется Encoding. Это означает, что TextWriter является интерфейсом к чему-то, что принимает поток символов , а также преобразует их в байты.

Это бесполезный остаток в StringWriter, потому что он не кодирует.documentation говорит:

Это свойство необходимо для некоторых сценариев XML, где заголовок должен быть записаны, содержащие кодировку, используемую StringWriter. Этот позволяет XML-коду потреблять произвольный StringWriter и генерировать правильный XML-заголовок.

Но это не может быть правдой, потому что нет никакого способа для нас, чтобы указать значение Encoding для StringWriter. Свойство всегда имеет значение UnicodeEncoding. Следовательно, любой код, который рассматривал это свойство для построения заголовка XML, всегда говорил бы utf-16. Например:

var stringWriter = new StringWriter(); 
using (var xmlWriter = XmlWriter.Create(stringWriter)) 
    xDocument.WriteTo(xmlWriter); 

Это дает заголовок:

<?xml version="1.0" encoding="utf-16"?> 

Что делать, если вы использовали File.WriteAllText, чтобы написать строку XML в файл? По умолчанию у вас будет файл utf-8 с заголовком utf-16.

В таких случаях было бы безопаснее использовать StreamWriter, и построить его с путем к файлу или FileStream, или если вы хотите, чтобы изучить данные затем использовать MemoryStream и так obtain an array of bytes. Все эти комбинации гарантируют, что кодирование в байтах и ​​генерация заголовка руководствовались тем же значением Encoding в вашем StreamWriter.

Целью свойства Encoding было дать возможность генераторам потоков символов включать точную информацию о кодировании в сам поток символов (например, в примере XML, другие примеры включают заголовки электронной почты и т. Д.).

Но, вводя StringWriter, эта связь между созданием контента и кодированием нарушена, и поэтому такие автоматические механизмы перестают работать и становятся потенциально подверженными ошибкам.

Тем не менее, StringWriter - полезный адаптер, если вы будете осторожны, то есть вы понимаете, что код генерации вашего контента не должен зависеть от бессмысленного значения свойства Encoding. Но такое предостережение обычно связано с шаблоном адаптера. Это часто своего рода хак, позволяющий вам вставлять квадратный-но-почти круглый штырь в круглое отверстие.

+0

@SandRock см. Второй абзац –

3

Основываясь на предыдущих (хороших) ответах, StringWriter на самом деле гораздо более универсален, чем StringBuilder, обеспечивая множество перегрузок.

Например:

Хотя StringBuilder только принимает строку или ничего для Appendline

StringBuilder sb = new StringBuilder(); 
sb.AppendLine("A string"); 

StringWriter может принять формат строки непосредственно

StringWriter sw = new StringWriter(); 
sw.WriteLine("A formatted string {0}", DateTime.Now); 

С StringBuilder необходимо это сделать (или используйте строку.Формат, или $ «»)

sb.AppendFormat("A formatted string {0}", DateTime.Now); 
sb.AppendLine(); 

Не делать или умереть вещи, но все-таки разница

1

StringBuilder и StringReader используются для повышения производительности в различных ситуациях.
ИспользуйтеStringBuilder, чтобы улучшить производительность при обработке строк, например, конкатенации, изменяя строку повторно.

Random rnd = new Random(); 
StringBuilder sb = new StringBuilder(); 

// Generate 10 random numbers and store in sb. 
for (int i = 0; i < 10; i++) 
{ 
    sb.Append(rnd.Next().ToString("N5")); 
} 
Console.WriteLine("The original string:"); 
Console.WriteLine(sb.ToString()); 

// Decrease each number by one. 
for (int ctr = 0; ctr < sb.Length; ctr++) 
{ 
    if (Char.GetUnicodeCategory(sb[ctr]) == System.Globalization.UnicodeCategory.DecimalDigitNumber) 
    { 
     int number = (int)Char.GetNumericValue(sb[ctr]); 
     number--; 
     if (number < 0) 
      number = 9; 

     sb[ctr] = number.ToString()[0]; 
    } 
} 
Console.WriteLine("\nThe new string:"); 
Console.WriteLine(sb.ToString()); 

ИспользованиеStringReader для разбора большого количества текста в отдельных строках и свести к минимуму использование памяти при обработке данных. См. Следующий пример, когда метод ReadLine на StringReader просто сканирует следующую новую строку, начиная с текущей позиции, а затем возвращает строку sbstring на основе строки поля.

using (StringReader sr = new StringReader("input.txt")) 
{ 
    // Loop over the lines in the string or txt file. 
    int count = 0; 
    string line; 
    while((line = sr.ReadLine()) != null) 
    { 
     count++; 
     Console.WriteLine("Line {0}: {1}", count, line); 
    } 
} 
+0

Пожалуйста, дайте объяснение для downvoting ... –

+0

приятный ответ .... – Unbreakable

Смежные вопросы