В чем разница между StringWriter
и StringBuilder
и когда следует использовать тот или иной?StringWriter или StringBuilder
ответ
A StringWriter
используется для ввода текста в память файл и StringBuilder
используется для добавления строк вместе в памяти эффективным способом.
StringBuilder
Используется для массового конкатенации строк. Это более эффективно для более чем 5 строк, насколько я знаю, тогда String.Concat()
. Также он может быть использован с конкретным форматом (.AppendFormat()
)
StringBuilder
классом является в основном изменяемыми строками, вспомогательным классом для конструкции непреложных строками. StringWriter
построен сверху, чтобы добавить дополнительные функции удобства для форматирования строк.
StringWriter
происходит от TextWriter
, что позволяет различным классам писать текст, не заботясь о том, куда он идет. В случае StringWriter
выход поступает в память. Вы использовали бы это, если вы вызываете API, которому требуется TextWriter
, но вы хотите только наращивать результаты в памяти.
StringBuilder
- это, по сути, буфер, который позволяет выполнять несколько операций (обычно прилагается) к «логической строке» без создания нового строкового объекта каждый раз. Вы должны использовать это для построения строки в нескольких операциях.
Я не думаю, что любой из существующих ответов действительно отвечает на вопрос. Фактическая взаимосвязь между двумя классами является примером 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
. Но такое предостережение обычно связано с шаблоном адаптера. Это часто своего рода хак, позволяющий вам вставлять квадратный-но-почти круглый штырь в круглое отверстие.
@SandRock см. Второй абзац –
Основываясь на предыдущих (хороших) ответах, 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();
Не делать или умереть вещи, но все-таки разница
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);
}
}
Пожалуйста, дайте объяснение для downvoting ... –
приятный ответ .... – Unbreakable
Ваш последний абзац применяется к String * Builder *, а не к StringWriter. –
Хмм .. MSDN сказал, что «StringWriter Class реализует TextWriter для записи информации в строку» http://msdn.microsoft.com/en-us/library/system.io.stringwriter.aspx – abatishchev