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 |
|---|---|
|
Escribe una cadena sin salto de línea |
|
Escribe una cadena con salto de línea |
|
Fuerza la escritura del buffer al archivo (rara vez necesario hacerlo a mano) |
/ |
Cierra el stream y libera el recurso (lo hace using) |
|
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í]
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.
GO TO FULL VERSION