2009-03-02 10 views

Respuesta

2

Un StringWriter se utiliza para escribir texto en una memoria de archivos y una StringBuilder se utiliza para añadir cadenas juntas de una manera eficiente en la memoria.

0

StringBuilder se utiliza para la concatenación masiva de cadenas. Es más efectivo para más de 5 cuerdas, hasta donde yo sé, entonces String.Concat(). También se puede utilizar con el formato específico (.AppendFormat())

+0

Su último párrafo se aplica al String * Builder *, no al StringWriter. –

+1

Hmm .. MSDN dijo que "StringWriter Class implementa un TextWriter para escribir información en una cadena" http://msdn.microsoft.com/en-us/library/system.io.stringwriter.aspx – abatishchev

3

La clase StringBuilder es básicamente una cadena mutable, una clase de ayuda a la construcción de una cadena inmutable. El StringWriter está construido en la parte superior para agregar más funciones de conveniencia para el formateo de cadenas.

54

StringWriter deriva de TextWriter, lo que permite que varias clases escriban texto sin importar a dónde va. En el caso de StringWriter, la salida solo está en la memoria. Utilizaría esto si está llamando a una API que necesita un TextWriter pero solo desea generar resultados en la memoria.

StringBuilder es básicamente un búfer que le permite realizar varias operaciones (generalmente se agrega) a una "cadena lógica" sin crear un nuevo objeto de cadena cada vez. Lo usarías para construir una cadena en múltiples operaciones.

69

No creo que ninguna de las respuestas existentes realmente responda la pregunta. La relación real entre las dos clases es un ejemplo de the adaptor pattern.

StringWriter implementa todos sus métodos Write... reenviando a una instancia de StringBuilder que almacena en un campo. Esto no es simplemente un detalle interno, porque StringWriter tiene un método público GetStringBuilder que devuelve el generador de cadenas interno, y también a constructor que le permite pasar un StringBuilder existente.

Así StringWriter es un adaptador que permite StringBuilder para ser utilizado como un objetivo por el código que espera trabajar con un TextWriter. En términos de comportamiento básico, claramente no hay nada que elegir entre ellos ... a menos que pueda medir la sobrecarga de reenviar las llamadas, en cuyo caso StringWriter es un poco más lento, pero parece muy poco probable que sea significativo.

¿Por qué no hicieron StringBuilder implementar TextWriter directamente? Esta es un área gris, porque la intención detrás de una interfaz no siempre es clara a primera vista.

TextWriter es muy cerca de una interfaz para algo que acepta una secuencia de caracteres. Pero tiene una arruga adicional: una propiedad llamada Encoding. Esto implica que TextWriter es una interfaz para algo que acepta una secuencia de caracteres y también los convierte en bytes.

Esto es un vestigio inútil en StringWriter porque no realiza ninguna codificación.El documentation dice:

Esta propiedad es necesaria para algunos escenarios XML en un encabezado debe escribirse que contiene la codificación utilizada por el StringWriter. Este permite que el código XML consuma un StringWriter arbitrario y genere el encabezado XML correcto.

Pero eso no puede ser cierto, porque no hay manera para nosotros para especificar el valor de Encoding para StringWriter. La propiedad siempre tiene el valor UnicodeEncoding. En consecuencia, cualquier código que examinara esta propiedad para construir un encabezado XML siempre diría utf-16. Por ejemplo:

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

que produce el encabezado:

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

Lo que si se ha utilizado File.WriteAllText para escribir su cadena XML en un archivo? De forma predeterminada, tendría un archivo utf-8 con un encabezado utf-16.

En estos escenarios sería más seguro de usar StreamWriter, y construir con una ruta de archivo, o una FileStream, o si se desea examinar los datos a continuación, utilizar un MemoryStream y así obtain an array of bytes. Todas estas combinaciones garantizarían que la codificación a bytes y la generación del encabezado estuvieran guiadas por el mismo valor Encoding en su StreamWriter. El objetivo de la propiedad Encoding era permitir que los generadores de secuencias de caracteres incluyeran información precisa sobre la codificación en la secuencia de caracteres en sí (como en el ejemplo XML, otros ejemplos incluyen encabezados de correo electrónico, etc.).

Pero al introducir StringWriter, ese vínculo entre la generación de contenido y la codificación se rompe, por lo que dichos mecanismos automáticos dejan de funcionar y se vuelven potencialmente propensos a errores.

Sin embargo, StringWriter es un adaptador útil si tiene cuidado, es decir, comprende que su código de generación de contenido no debe depender del valor sin sentido de la propiedad Encoding. Pero ese tipo de advertencia comúnmente se asocia con el patrón del adaptador. A menudo es una especie de truco que te permite colocar una clavija cuadrada casi redonda en un agujero redondo.

+0

@SandRock ver el segundo párrafo –

3

Sobre la base de las respuestas anteriores (buenas), StringWriter es en realidad mucho más versátil que StringBuilder, proporcionando muchas sobrecargas.

Por ejemplo:

Mientras StringBuilder sólo acepta una cadena o nada para Appendline

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

StringWriter puede tener un formato de cadena directamente

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

Con StringBuilder uno debe hacer esto (o usar una cuerda.Formato, o $ "")

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

No hacer o morir cosas, pero sigue habiendo una diferencia

1

StringBuilder y StringReader se utilizan para mejorar el rendimiento en diferentes situaciones.
UtiliceStringBuilder para mejorar el rendimiento en la manipulación de cadenas, como la concatenación, la modificación de cadena repetidamente.

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

UsoStringReader para analizar una gran cantidad de texto en líneas separadas y minimizar el uso de memoria durante el procesamiento de datos. Vea el siguiente ejemplo donde el método ReadLine en StringReader simplemente busca la próxima línea nueva comenzando en la posición actual, y luego regresa una cadena basada en la cadena del campo.

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

Proporcione una explicación para la votación negativa ... –

+0

nice answer .... – Unbreakable