1. Codificación por defecto
Cuando trabajas con StreamReader o StreamWriter, usan una codificación por defecto.
Si escribes:
using var reader = new StreamReader("myfile.txt");
o
using var writer = new StreamWriter("output.txt");
.NET elige la codificación por defecto. En Windows esto suele ser UTF-8 (a menudo sin BOM), pero en apps antiguas o al ejecutarlo en otros sistemas el comportamiento puede variar.
En la mayoría de casos UTF-8 es una buena opción: soporta todos los idiomas y almacena de forma compacta el texto en inglés (y también funciona bien con ruso). Pero si el archivo fue creado en otra codificación (por ejemplo, en Windows-1251), o lo van a leer otras herramientas que esperan una codificación concreta, necesitas indicarla explícitamente.
2. Especificar la codificación para StreamReader y StreamWriter
Variantes de constructores
Tanto StreamReader como StreamWriter tienen constructores en los que puedes pasar un objeto de tipo System.Text.Encoding.
Ejemplo:
using var reader = new StreamReader("myfile.txt", Encoding.UTF8);
using var writer = new StreamWriter("output.txt", false, Encoding.UTF8);
Si quieres trabajar con ASCII, Windows-1251 o UTF-16, simplemente usa otra codificación:
using var reader = new StreamReader("myfile.txt", Encoding.Unicode); // UTF-16
using var reader2 = new StreamReader("rus.txt", Encoding.GetEncoding("windows-1251"));
Tabla breve de codificaciones populares:
| Codificación | Expresión en C# | Descripción |
|---|---|---|
| UTF-8 | |
Soporta todos los idiomas, compacto |
| UTF-16 (Unicode) | |
Estándar de .NET, 2 bytes por carácter |
| ASCII | |
Sólo caracteres básicos (inglés) |
| Windows-1251 | |
Ruso, programas antiguos de Windows |
¡Atención! Para codificaciones no estándar como Windows-1251 usa el método Encoding.GetEncoding("windows-1251").
3. Leer y escribir especificando la codificación
Añadamos a nuestra mini-app un nuevo funcionalidad: que lea un archivo en la codificación indicada y escriba el resultado en un nuevo archivo, también con la codificación explícita. De este modo puedes, por ejemplo, convertir texto entre diferentes sistemas.
Ejemplo 1: Leer un archivo en Windows-1251 y mostrarlo por pantalla
// Supongamos que el archivo fue creado con la antigua Windows-1251
using var reader = new StreamReader("ru_text.txt", Encoding.GetEncoding("windows-1251"));
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
Por qué esto importa: Si no hubiéramos especificado la codificación, en vez de letras rusas obtendríamos caracteres horribles como "УчебнРиК".
Ejemplo 2: Escribir un archivo en UTF-16 (Unicode)
using var writer = new StreamWriter("utf16text.txt", false, Encoding.Unicode);
writer.WriteLine("¡Hola, mundo!");
writer.WriteLine("Hello, world!");
writer.WriteLine("こんにちは世界");
Resultado: Abriendo el archivo, por ejemplo, en Notepad, verás que todos los caracteres se muestran correctamente.
4. Pequeña utilidad para convertir codificaciones
Ejercicio (¡que a menudo aparece en entrevistas!): Convertir un archivo de texto de la codificación Windows-1251 a UTF-8.
string sourcePath = "ru_text_1251.txt";
string destPath = "ru_text_utf8.txt";
// Leemos con la codificación Windows-1251
using var reader = new StreamReader(sourcePath, Encoding.GetEncoding("windows-1251"));
// Escribimos en UTF-8
using var writer = new StreamWriter(destPath, false, Encoding.UTF8);
string? line;
while ((line = reader.ReadLine()) != null)
writer.WriteLine(line);
Ahora ru_text_utf8.txt se puede abrir sin problemas en VSCode, Linux, Mac y ver el texto legible.
5. Consejos útiles
¿Cómo saber en qué codificación está un archivo?
¡Es una pregunta tramposa! Normalmente el archivo no guarda información sobre su codificación (salvo los archivos con BOM, de eso hablaremos en la próxima clase). Si abres un archivo con la codificación equivocada, el resultado son garabatos.
Enfoques prácticos típicos:
- Si el archivo fue creado por tu programa — usa siempre la misma codificación para leer que la que usaste al escribir.
- Si el archivo viene de una fuente desconocida — prueba diferentes codificaciones o usa utilidades externas para detectarla.
Trabajar con emojis y símbolos inusuales
UTF-8 y UTF-16 permiten usar libremente emojis y símbolos de distintos idiomas. Prueba a guardar un archivo con emojis en UTF-8 y luego ábrelo con una codificación antigua — será divertido (o no).
Código con emojis:
using var writer = new StreamWriter("emoji.txt", false, Encoding.UTF8);
writer.WriteLine("¡Hola 👋😀🌍");
StreamReader con detección automática de codificación
El constructor de StreamReader tiene una sobrecarga con el parámetro detectEncodingFromByteOrderMarks:
new StreamReader(path, encoding, detectEncodingFromByteOrderMarks: true)
Si ese parámetro es true (¡es el valor por defecto!), StreamReader intentará adivinar la codificación por la presencia de BOM (una "marca" especial al principio del archivo). Pero si el archivo fue creado sin BOM o usa una codificación exótica, la detección no funcionará.
¿Cuándo y por qué especificar la codificación explícitamente?
- Datos multilingües: soporte para árabe, chino, emojis, etc.
- Integraciones: el archivo lo lee/escribe no solo tu programa, sino otro sistema que espera una codificación específica.
- El tamaño del archivo importa: ASCII/UTF-8 son más eficientes para texto latino, UTF-16 puede ser mejor para ideogramas.
- Compatibilidad: logs/export para otras aplicaciones.
6. Errores típicos al trabajar con codificaciones
Error nº 1: no especificar explícitamente la codificación al leer un archivo.
Leer un archivo con texto ruso (o cualquier otro texto no latino) sin indicar la codificación suele dar como resultado texto ininteligible.
Error nº 2: desajuste entre la codificación usada para escribir y la que se usa para leer.
El archivo se escribió en una codificación y se abrió con otra — el texto queda corrupto. Suele pasar al mover archivos entre distintos SO o programas.
Error nº 3: codificaciones no soportadas o con soporte parcial.
Algunos editores manejan mal UTF-8 sin BOM o las viejas codificaciones monobáiticas como Windows-1251. A veces toca cambiar la codificación manualmente y probar.
GO TO FULL VERSION