IO 101: ¿Cuáles son las principales diferencias entre TextWriter, FileStream y StreamWriter?

StackOverflow https://stackoverflow.com/questions/1010555

  •  06-07-2019
  •  | 
  •  

Pregunta

Permítanme primero disculparme si esta pregunta puede sonar como una especie de aficionado para los programadores experimentados entre ustedes, la cuestión es que he estado teniendo muchos argumentos sobre esto en el trabajo, así que realmente quiero aclarar esto y es básicamente por eso que confío en la comunidad stackoverflow para resolver esto de una vez por todas :)

Entonces, por un lado de acuerdo con MSDN, tenemos:

  

Clase TextWriter

     

Representa a un escritor que puede escribir un   Serie secuencial de personajes. Esta   la clase es abstracta.

     

Clase FileStream

     

Expone una secuencia alrededor de un archivo,   compatible tanto sincrónico como   lectura y escritura asincrónicas   operaciones.

     

Clase StreamWriter

     

Implementa un TextWriter para escribir   caracteres a una secuencia en un particular   codificación.

Por otro lado, es evidente que todos pertenecen a System.IO, pero dado que los ejemplos de MSDN combinan algunos de ellos, todavía no estoy alcanzando el tan deseado momento a-ha.

Cualquier comentario sería más que apreciado, ¡muchas gracias de antemano!

¿Fue útil?

Solución

Las secuencias manejan bytes , los escritores manejan caracteres .

Bytes! = caracteres. Un personaje puede tomar más de un byte para representar. La asignación de caracteres a bytes se denomina codificación .

Un FileStream se refiere a los bytes que se escriben en un archivo, de forma similar a como un MemoryStream se refiere a los bytes escritos en un búfer en memoria. Para escribir caracteres en una secuencia, necesitaría convertirlos en una cadena de bytes. Ahí es donde entra en juego un StreamWriter . Toma una secuencia de caracteres y una codificación, y la convierte en una secuencia de bytes.

Un TextWriter es una interfaz (bueno, clase base abstracta) a la que deben adherirse todos los escritores. Tiene todas las operaciones basadas en personajes. El equivalente para bytes es la clase base abstracta Stream .

Las cosas también van en la dirección opuesta. Hay una clase base abstracta TextReader , que describe cómo leer caracteres desde algún lugar, y un StreamReader , que le permite leer caracteres de una secuencia orientada a bytes que proporciona una codificación: pero esta vez se usa en reversa, para agregar cualquier secuencia de varios bytes en caracteres únicos cuando corresponda.

Un Stream se puede usar tanto para leer como para escribir, ya que los bytes son los elementos de nivel más bajo utilizados en las operaciones de E / S.

Otros consejos

Siempre he encontrado que lo mejor es mirar qué métodos proporcionan y cómo puedes construirlos. Esto es casi siempre lo principal, si no solo, lo que me importa cuando uso una API. ¿Cómo lo construyo y qué puede hacer?

No puede crear una instancia de un TextWriter. Es abstracto. Eso me dice que el único propósito real al que sirve es, bueno, la abstracción. Si escribe una función que toma cualquier tipo de escritor como argumento, hay una buena posibilidad de que simplemente tome TextWriter para ser más versátil.

Un StreamWriter puede crear instancias, y hace exactamente lo que dice, escribe en streams. Eso significa que necesitará una transmisión para realizar cualquier escritura real. Sin embargo, una vez que tenga esa secuencia, puede hacer todo tipo de cosas buenas como escribir una línea completa a la vez en lugar de tener que lidiar con caracteres individuales (o más bien bytes) como lo haría directamente en la secuencia.

Entonces, básicamente, obtienes una secuencia para poder alimentarla a un StreamWriter (o Reader). Si está escribiendo texto, probablemente no desee trabajar directamente con una secuencia, no más de lo que desea trabajar con una matriz de caracteres en lugar de una cadena.

FileStreams puede ser convenientemente instanciado directamente desde las clases File y FileInfo, y en mi uso, así es como generalmente se instancian. Obtenga un archivo (me gusta usar FileInfo) y llame a OpenWrite (). Pásalo a un StreamWriter (que es solo un tipo de TextWriter) y estarás en camino.

Para generalizar: cuando desee averiguar una clase, intente ver cómo crear una instancia y qué puede hacer. Esto generalmente aclara mucho.

Hay una diferencia obvia entre un " Stream " y un "Escritor / Lector".

Un flujo es una representación a nivel de byte, y es realmente un concepto abstracto que se puede implementar de varias maneras. Por ejemplo, tiene un FileStream y un MemoryStream. Ambos son flujos de bytes, pero se almacenan de manera diferente.

Los escritores y lectores le brindan una forma de procesar transmisiones, agregando y extrayendo datos de ellas.

Para sus ejemplos particulares, TextWriter es una clase abstracta que escribe caracteres secuencialmente en una secuencia. Tiene varias implementaciones (StreamWriter, StringWriter) que son útiles en diferentes contextos. Usaría lo que tenga sentido en ese momento. Sin embargo, para varias API, todo lo que se necesita es un TextWriter, o algo a lo que llamar "Escribir". o '' WriteLine '' en. No es una preocupación de esas API si su escritor se usa para poner cosas en una cadena, alguna memoria arbitraria o un archivo.

La clase FileStream logra obtener un identificador a un archivo y abrirlo para leer o escribir y otras funciones del sistema de archivos. BinaryWriter escribe datos binarios en una secuencia y StreamWriter escribe datos de caracteres en una secuencia. Ambos pueden usar un objeto FileStream para escribir datos binarios o de caracteres en los archivos.

TextWriter es la clase base de la que StreamWriter hereda. Un TextWriter está destinado a tomar un tipo y generar una cadena utilizando su Método de escritura . La implementación de StreamWriter del método TextWriter.Write escribe una cadena o datos de caracteres en una secuencia. BinaryWriter no hereda TextWriter porque no escribe datos de caracteres en una secuencia.

Stream es una clase base abstracta que representa una serie de bytes.

  • MemoryStream es una secuencia de bytes retenidos en la memoria, respaldada por una matriz.

  • FileStream es una secuencia de bytes en un archivo, generalmente respaldada por un identificador de archivo en algún lugar del disco.

Los caracteres de texto están compuestos por bytes, y un solo carácter puede tener varios bytes, dependiendo de la codificación. Hay algunas clases estándar que leen y escriben texto en diferentes fuentes usando una codificación específica.

TextWriter es una clase base abstracta para escribir caracteres de texto en un destino.

  • StreamWriter escribe caracteres de texto (convertidos a bytes) en una secuencia de bytes.
  • StringWriter escribe caracteres de texto en una cadena (a través de un StringBuilder).

TextReader es una clase base abstracta para leer caracteres de texto de una fuente.

  • StreamReader lee caracteres de texto (convertidos de bytes) de una secuencia de bytes.
  • StringReader lee caracteres de texto de una cadena.

Stream , TextWriter , TextReader son todas clases base abstractas, por lo que nunca se usan directamente sino a través de una implementación como las descritas anteriormente. Sin embargo, verá las clases base en las definiciones de métodos para que se puedan utilizar diferentes implementaciones, incluidas las suyas personalizadas si es necesario. Las clases abstractas son similares a las interfaces, pero en realidad pueden definir la lógica de los métodos, que pueden reutilizarse sin que cada implementación repita el mismo código básico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top