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.
También te puede interesar
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.
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.