CodeGym /Cursos /C# SELF /Escritura de archivos de texto:

Escritura de archivos de texto: StreamWriter

C# SELF
Nivel 36 , Lección 3
Disponible

1. Introducción

StreamWriter es una de las clases clave del espacio de nombres System.IO en .NET, pensada para escribir datos de texto en archivos a través de un stream.

¿Por qué no trabajar directamente con FileStream?
FileStream solo trabaja con bytes. Si intentas escribir una cadena con él, tendrás que convertir el texto a bytes tú mismo y preocuparte por la codificación (y seguro que después vas a querer volver a StreamWriter).
StreamWriter se encarga de todo eso: tú le das una cadena y él escribe los bytes correctos en el archivo.

Ventajas principales:

  • Escribes cadenas fácilmente, sin pensar en convertirlas a bytes.
  • Tiene métodos para escribir texto línea por línea.
  • Control de buffer y codificación (y vamos a aprender a usarlo).

Ejemplo básico

using System.IO;

string path = "output.txt";

using (StreamWriter writer = new StreamWriter(path))
{
    writer.WriteLine("¡Hola, mundo!");
    writer.WriteLine("Esta es la segunda línea.");
}
// Al salir de las llaves del using, StreamWriter libera el archivo sí o sí.

¿Qué pasa aquí?

  • Se abre el archivo para escribir (si no existe, se crea).
  • Cada cadena se escribe como una línea separada en el archivo (método WriteLine).
  • Después del bloque using el archivo se cierra automáticamente, incluso si hay errores.

Si abres el archivo output.txt después de ejecutar este programa, verás dos líneas de texto, tal cual como se esperaba.

Un matiz importante

Si el archivo ya existe, se va a sobrescribir desde cero. Todo lo que había dentro — desaparece. Así que ojo: no guardes aquí tu tesis o el único recibo de la luz.

2. Escritura de datos en el stream

Métodos principales de StreamWriter

Método Descripción
Write(string)
Escribe una cadena sin salto de línea
WriteLine(string)
Escribe una cadena con salto de línea
Flush()
Fuerza la escritura del buffer al archivo (rara vez necesario hacerlo a mano)
Close()
/
Dispose()
Cierra el stream y libera el recurso (lo hace using)
BaseStream
Acceso al stream base (por ejemplo, FileStream)

Método Write()

Escribe datos sin salto de línea. Todo lo que escribas después va en la misma línea del archivo.

Método WriteLine()

Escribe datos añadiendo automáticamente el carácter de fin de línea (\r\n en Windows, \n en sistemas tipo Unix).
Es como pulsar Enter después de cada escritura.

Write() vs WriteLine(): demostración de la diferencia

using (var writer = new StreamWriter("example.txt"))
{
    writer.Write("Primer ");
    writer.Write("párrafo. ");
    writer.WriteLine("Terminamos la línea, ¡Enter!");
    writer.Write("Segundo párrafo.");
}

Ahora example.txt se verá más o menos así:

Primer párrafo. Terminamos la línea, ¡Enter!
Segundo párrafo.

3. Trabajo con codificaciones

Por defecto, al crear un StreamWriter sin parámetros, se usa la codificación UTF-8 con BOM (Byte Order Mark).

En la práctica esto es cómodo y moderno, pero a veces hay que especificar la codificación — por ejemplo, para compatibilidad con programas antiguos o datos importados.

¿Cómo indicar la codificación?

// Escribir archivo en codificación Windows-1251 (cirílico para sistemas antiguos)
using (var writer = new StreamWriter("cyrillic.txt", false, System.Text.Encoding.GetEncoding("windows-1251")))
{
    writer.WriteLine("¡Hola, mundo cirílico!");
}

Punto importante:
La codificación debe estar soportada en el sistema. Si no estás seguro — usa UTF-8.

4. Parámetros adicionales del constructor

Vamos a ver las tripas de StreamWriter:

public StreamWriter(
    string path,              // ruta al archivo
    bool append = false,      // ¿añadir al final del archivo?
    Encoding encoding = null, // codificación
    int bufferSize = 1024     // tamaño del buffer, bytes
)
  • append — si es false (por defecto), el archivo se sobrescribe. Si es true, los nuevos datos se añaden al final.
  • encoding — codificación usada.
  • bufferSize — tamaño del buffer interno para acelerar el trabajo con grandes volúmenes de datos.

Ejemplo: añadir al mismo archivo

// El archivo se va a añadir, no sobrescribir
using (var writer = new StreamWriter("log.txt", append: true))
{
    writer.WriteLine(DateTime.Now + " -- Nuevo evento");
}

5. Trucos útiles

¿Qué pasa al añadir o sobrescribir?

Modo ¿Qué hace? Resultado en el archivo
append: false Sobrescribe todo desde cero Los datos antiguos se borran
append: true Añade nuevas líneas al final Las líneas antiguas se conservan

Tip: El modo de añadir (append: true) es perfecto para logs, cuando quieres guardar el historial de eventos.

StreamWriter y grandes volúmenes de datos

  • StreamWriter usa buffer: los datos reales llegan al archivo un poco después de llamar a WriteLine. Pero tras cerrar el stream (o llamar a Flush()) todo está garantizado en disco.
  • Escribir con WriteLine es súper eficiente para salida línea a línea. Para formatos complejos (JSON, CSV o XML) mejor usa librerías específicas, o escapa bien los caracteres especiales (como comas o comillas).

Cómo cerrar bien la escritura y liberar recursos

La forma correcta: ¡usa siempre using!
Así te aseguras de que el archivo se cierra incluso si hay una excepción (por ejemplo, si el disco "se acaba" de repente o el archivo está bloqueado por otro programa).


flowchart TD
    A[Creación de StreamWriter] --> B[Trabajo con el archivo]
    B --> C{¿Excepción?}
    C -- Sí --> D[Se llama a Dispose]
    C -- No --> D
    D --> E[Archivo cerrado sí o sí]
Esquema: using garantiza el cierre del archivo incluso con errores

6. Ejemplos prácticos

Supón que en el curso tenemos un mini-programa para llevar el control de libros. Vamos a añadir la funcionalidad de guardar nuevos libros en un archivo.

Ejemplo: Guardar un libro nuevo en un archivo separado

using System;
using System.IO;

class Program
{
    static void Main()
    {
        Console.WriteLine("Introduce el título del libro:");
        string bookTitle = Console.ReadLine();

        Console.WriteLine("Introduce el autor:");
        string author = Console.ReadLine();

        string path = "books.txt";
        using (var writer = new StreamWriter(path, append: true))
        {
            writer.WriteLine($"{bookTitle};{author}");
            // Formato CSV: cada línea es un libro, separado por punto y coma
        }

        Console.WriteLine("¡Libro guardado en el archivo!");
    }
}

Prueba a añadir varios libros seguidos. En el archivo books.txt las líneas se irán añadiendo sin borrar las anteriores. Este comportamiento es muy útil para logs o historiales — por ejemplo, para tu futuro sistema de auditoría cuando seas un desarrollador Enterprise.

7. Cómo evitar errores típicos al escribir en archivo

La mayoría de los novatos se topan con estos problemas:

Archivo no cerrado y bloqueado por otro proceso. Motivo — te olvidaste del using.

Escribiste muchas líneas pero el archivo quedó vacío: te olvidaste de llamar a Flush() o cerrar el stream (con using esto va solo).

Sobrescribiste el archivo sin querer en vez de añadir — te olvidaste de poner append: true.

Problemas de codificación: el archivo se ve "rarito" en el Bloc de notas — elegiste la codificación equivocada o el otro programa no soporta UTF-8.

Excepciones UnauthorizedAccessException o DirectoryNotFoundException: el programa intenta guardar el archivo donde no tiene permisos, o en una carpeta que no existe. Revisa la ruta y los permisos.

Error "file is used by another process": abriste el archivo para escribir pero no lo cerraste, o alguien más intenta escribir al mismo tiempo.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION