c# .net c#-3.0 stringbuilder stringreader

c# - StringBuilder Vs StringWriter/StringReader



.net c#-3.0 (4)

Recientemente leí que en StringWriter y StringReader se usan para escribir y leer de StringBuilder .

Bueno, cuando uso el objeto StringBuilder , parece ser una clase autosuficiente.

Tenemos todas las formas de leer y escribir el StringBuilder , usando StringBuilder.Append() , Insert() , Replace() , Remove() etc.

  1. ¿Cuál es el posible uso de StringWriter y StringReader , que StringBuilder no puede hacer por sí mismo?
  2. ¿Cuál es el uso práctico de ellos?
  3. ¿Cuál podría ser la posible razón por la que no están tomando el Stream como la entrada (porque cualquier otro escritor y lector está tomando el stream como el parámetro Constructor para operar) pero el StringBuilder ?

¿Cuál es el posible uso de StringWriter y StringReader, que StringBuilder no puede hacer por sí mismo?

StringReader y StringWriter derivan de TextReader y TextWriter respectivamente. Entonces, lo que pueden hacer es actuar como una instancia de TextReader o TextWriter , que string o StringBuilder no pueden porque no derivan ninguno de esos tipos.

¿Cuál es el uso práctico de ellos?

Le permiten llamar a las API que esperan un TextReader o TextWriter , cuando lo que tiene / desea es una string o StringBuilder .

¿Cuál podría ser la posible razón por la que no están tomando el Stream como la entrada (porque cualquier otro escritor y lector está tomando el stream como el parámetro Constructor para operar) pero el StringBuilder?

Porque no funcionan en corrientes; trabajan en la string s o StringBuilder s. Solo son simples clases de envoltura que adaptan estos tipos para API que esperan una interfaz diferente. Ver: patrón adaptador .


No estoy seguro de quién te dijo que su propósito era para el uso con StringBuilder, pero eso es absolutamente incorrecto. Como notaste, StringBuilder puede ser leído y escrito sin el uso de otra clase. Las clases StringWriter y StringReader amplían las clases base TextReader y TextWriter .Net Framework y proporcionan funciones similares a las de la corriente para trabajar con datos textuales. Por ejemplo, si necesita trabajar con algunas de las clases de tipo XmlDocument, algunos de los métodos le permiten cargar los datos Xml a través de un TextReader, así que si tiene el texto Xml como una variable de cadena, podría cargarlo en un StringReader y luego suministrarlo al XmlDocument.


Otros ya lo han dicho, pero es porque se derivan de TextReader / TextWriter y se pueden usar en lugar de ellos. Por un lado, tiene más sentido usar el mismo método para generar las líneas que usa para un archivo si solo desea el contenido como una cadena. Si desea una salida que abarque varias líneas en la memoria, ¿por qué molestarse en recordar poner "/ r / n" al final de cada línea con un StringBuilder? ¿Qué sucede si desea que el código se ejecute o formatee datos para un sistema que solo usa "/ n" para los saltos de línea?

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

Digamos que quiere procesar un archivo línea por línea, probablemente usaría un StreamReader en lugar de cargar todo el archivo en un StringBuilder y dividirlo por caracteres de nueva línea en una matriz, ¿no? Con StringReader puede usar el mismo método exacto (siempre y cuando tome un TextReader genérico) creando el StringReader a partir de una cadena de un TextBox o formulario web.

Linq2Sql DataContexts tiene una propiedad de registro que puede configurar en un TextWriter para que sus consultas salgan antes de que se ejecuten para ver exactamente qué se está ejecutando. Puede establecer esto en un TextWriter adjunto a un archivo, pero puede adjuntar un StringWriter y mostrar el contenido en la parte inferior de su página web al probar ...


Puedes usar StringReader para leer todos los enteros de una cadena.

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

Clase de entrada estándar:

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