2010-08-03 22 views
26

Recientemente leí que en StringWriter y StringReader se utilizan para escribir y leer en StringBuilder.StringBuilder Vs StringWriter/StringReader

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

Tenemos todas las formas de lectura y escritura del StringBuilder, utilizando StringBuilder.Append(), Insert(), Replace(), etc ... Remove()

  1. ¿Cuál es el posible uso de StringWriter y StringReader, que no se puede hacer por StringBuilder ¿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 Stream como entrada (porque cualquier otro escritor y lector están tomando la secuencia como el parámetro Constructor para operar) pero el StringBuilder?
+1

duplicado posible de [StringWriter o StringBuilder] (http://stackoverflow.com/questions/602279/stringwriter-or-stringbuilder) –

Respuesta

31

¿Cuál es el uso posible de StringWriter y StringReader, que no puede ser realizado por StringBuilder?

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

¿Cuál es su uso práctico?

Ellos le permiten llamar a las API que están esperando un TextReader o TextWriter, cuando lo que tiene/quiere es un string o StringBuilder.

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

Porque no funcionan en las transmisiones; trabajan en string so StringBuilder s. Son simplemente clases contenedoras simples que adaptan estos tipos para las API que esperan una interfaz diferente. Ver: adapter pattern.

1

No estoy seguro de quién le dijo que su propósito era para usarlo con StringBuilder, pero eso es absolutamente incorrecto. Como notó, StringBuilder puede leerse y escribirse sin el uso de otra clase. Las clases StringWriter y StringReader amplían las clases base de TextReader y TextWriter .Net Framework y brindan características de flujo para trabajar con datos de texto. 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, de modo que si tiene el texto Xml como una variable de cadena, puede cargarlo en un StringReader y luego suministrarlo al XmlDocument.

+0

Hola, gracias por su responder. Estoy de acuerdo con el punto que se deriva de TextWriter/TextReader. He tomado StringWriter por ejemplo y encontré que las dos siguientes inicializaciones no funcionan. 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); Solo se necesita Stringbuilder para escribir. – SaravananArumugam

+1

@Saravanandss - Si intenta leer/escribir desde/a secuencias, entonces use 'StreamReader' y' StreamWriter' ... para eso están. 'StringReader' y' StringWriter' no están diseñados para trabajar con archivos; están diseñados para trabajar con cadenas. ¿Por qué estás tratando de usarlos? –

5

Otros ya lo han dicho, pero es porque derivan de TextReader/TextWriter y se pueden usar en lugar de ellos.Por un lado, tiene más sentido utilizar el mismo método para generar líneas que utiliza 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); 

decir que quiere procesar un archivo línea por línea, es probable que utilice un StreamReader en lugar de cargar todo el archivo en un StringBuilder y la división por caracteres de nueva línea en una matriz, ¿verdad? Con StringReader puede usar exactamente el mismo método (siempre que tome un TextReader genérico) creando el StringReader a partir de una cadena de un TextBox o formulario web.

Los DataContexts de Linq2Sql tienen una propiedad de registro que puede establecer en un TextWriter para generar sus consultas 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 ...

1

Puede usar StringReader para leer todos los enteros de un cuerda.

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 Clase:

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