C# Leer archivo de texto

Hay tres formas de leer, y la diferencia está en cuánta memoria usan. Para un archivo de configuración da igual cuál elijas; para uno de varios gigas, solo una de ellas funciona.

Sin namespace, sin class Program, sin Main. Los ejemplos usan instrucciones de nivel superior, disponibles desde C# 9: el compilador genera esa estructura por ti. Y desde .NET 10 un archivo suelto se ejecuta directamente con dotnet run archivo.cs, sin crear un proyecto. El código de siempre, con su static void Main, sigue funcionando igual. Tampoco hacen falta los using System;, System.IO y compañía: los proyectos modernos los incluyen de forma implícita.

Entero o por líneas

string ruta = Path.Combine("salida", "notas.txt");

string todo = File.ReadAllText(ruta);
Console.WriteLine($"ReadAllText: {todo.Length} caracteres");

string[] lineas = File.ReadAllLines(ruta);
Console.WriteLine($"ReadAllLines: {lineas.Length} líneas -> {string.Join(" | ", lineas)}");
salidaReadAllText: 42 caracteres
ReadAllLines: 3 líneas -> Primera línea | Segunda línea | Tercera línea

Las dos cargan el archivo entero en memoria. ReadAllLines devuelve las líneas ya sin el salto final, y entiende tanto el de Windows como el de Linux.

Sin cargarlo todo: File.ReadLines

int n = 0;
foreach (string linea in File.ReadLines(ruta))
    Console.WriteLine($"{++n}: {linea}");
salida1: Primera línea
2: Segunda línea
3: Tercera línea
ReadLines y ReadAllLines se diferencian en tres letras y en todo lo demás. ReadAllLines lee el archivo completo y devuelve un arreglo. ReadLines lo va leyendo según el foreach pide la siguiente línea: con un registro de 5 GB, la primera se queda sin memoria y la segunda ni se inmuta. Si solo vas a recorrer el archivo una vez, usa ReadLines.

Con StreamReader

using var lector = new StreamReader(ruta);
string? l;
while ((l = lector.ReadLine()) is not null)
    if (l.StartsWith("Seg"))
        Console.WriteLine($"encontrada: {l}");
salidaencontrada: Segunda línea

Lo mismo que ReadLines, con más control: puedes parar cuando encuentres lo que buscas o leer bloques. El using var cierra el archivo al terminar el método.

Si no existe

salidaFileNotFoundException: Could not find file '/trabajo/no_existe.txt'.

Se captura con catch (FileNotFoundException e). Si lo que falta es la carpeta, la excepción es otra: DirectoryNotFoundException. Las dos heredan de IOException.

La versión anterior de esta página usaba rutas como C:\RutaArchivos\ o D:\dev\proyCs\, que solo existían en un ordenador. Aquí se usan rutas relativas y Path.Combine, que pone el separador correcto en cada sistema: el mismo código funciona en Windows, Linux y macOS.

Todo el código se ejecutó con .NET 10 en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.

Deja un comentario