¿Por qué saber trabajar con archivos en C# es un superpoder?
\n\nImagina que estás escribiendo un programa que debe guardar la configuración del usuario, registrar errores o procesar miles de documentos. Sin habilidades para trabajar con el sistema de archivos, te estrellarás contra una pared. En C#, trabajar con archivos no es solo una aburrida lectura de líneas. Es la oportunidad de crear potentes utilidades, analizadores sintácticos e incluso mini bases de datos.
\n\nEn este artículo, lo desglosaremos todo: desde lo básico File.ReadAllText hasta el trabajo avanzado con flujos y carpetas. Aprenderás cómo no perder datos, cómo optimizar la lectura de archivos grandes y cómo sortear los "escollos" del sistema de archivos. ¡Allá vamos!
Clases héroe: File, FileInfo, Directory y Path
\n\nEn .NET hay dos enfoques para trabajar con archivos: los métodos estáticos de la clase File y los métodos de instancia de la clase FileInfo. El primero es para operaciones rápidas de "leer y escribir", el segundo es cuando necesitas trabajar con un solo archivo durante mucho tiempo y conservando el estado.
File vs FileInfo: ¿cuándo usar cada uno?
\n\nFile es una clase estática. Escribes File.Exists("test.txt") y listo. Es conveniente, pero en cada operación el sistema verifica la ruta de nuevo.
FileInfo: creas el objeto una vez y luego llamas a los métodos. Es más rápido si realizas varias acciones con un mismo archivo.
\n\n// Forma rápida\nif (File.Exists(@"C:\\data\\log.txt"))\n{\n string content = File.ReadAllText(@"C:\\data\\log.txt");\n Console.WriteLine(content);\n}\n\n// Forma profesional\nFileInfo fileInfo = new FileInfo(@"C:\\data\\log.txt");\nif (fileInfo.Exists)\n{\n using (StreamReader reader = fileInfo.OpenText())\n {\n string content = reader.ReadToEnd();\n Console.WriteLine(content);\n }\n}\n\n\nLa clase Directory funciona con el mismo principio: métodos estáticos para operaciones rápidas con carpetas. Path es un asistente indispensable para unir rutas: Path.Combine("folder", "file.txt") coloca automáticamente la barra diagonal correcta.
Lectura de archivos: de pequeño a gigante
\n\nLa lectura de archivos en C# es un arte de equilibrio entre simplicidad y rendimiento. Analicemos tres niveles.
\n\nNivel 1: Todo de una vez (para archivos pequeños)
\n\nSi el archivo pesa hasta 10 MB, usa sin miedo ReadAllText o ReadAllLines.
string text = File.ReadAllText("config.json");\nstring[] lines = File.ReadAllLines("users.csv");\n\n\nInconveniente: con un archivo grande corres el riesgo de obtener un OutOfMemoryException.
Nivel 2: Lectura línea por línea (para archivos medianos)
\n\nUsamos StreamReader: leemos línea por línea sin cargar todo en memoria.
using (StreamReader reader = new StreamReader("big_log.txt"))\n{\n string line;\n while ((line = reader.ReadLine()) != null)\n {\n Console.WriteLine(line); // Procesamos cada línea\n }\n}\n\n\nObserva el using: garantiza que el archivo se cierre, incluso si ocurre un error.
Nivel 3: Lectura de datos binarios (para profesionales)
\n\nTrabajar con imágenes, archivos comprimidos o cualquier archivo no textual requiere FileStream.
using (FileStream fs = new FileStream("photo.jpg", FileMode.Open, FileAccess.Read))\n{\n byte[] buffer = new byte[1024];\n int bytesRead;\n while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)\n {\n // Procesamos el fragmento de datos\n Console.WriteLine($"Leídos {bytesRead} bytes");\n }\n}\n\n\nEscritura de archivos: cómo no perder datos
\n\nEscribir en C# no es solo File.WriteAllText. Es importante entender los modos: crear un archivo nuevo, añadir al final o sobrescribir.
Modos principales de FileMode
\n- \n
- CreateNew - Crea un nuevo archivo. Lanza una excepción si el archivo ya existe. \n
- Create - Crea un nuevo archivo. Si el archivo existe, lo sobrescribe. \n
- Open - Abre un archivo existente. Lanza una excepción si el archivo no existe. \n
- OpenOrCreate - Abre el archivo si existe, o crea uno nuevo si no. \n
- Append - Abre el archivo y se posiciona al final para añadir datos. Crea el archivo si no existe. \n
Ejemplo: escritura con StreamWriter
\n\nusing (StreamWriter writer = new StreamWriter("output.txt", append: true))\n{\n writer.WriteLine("Nueva línea de registro");\n writer.WriteLine($"Fecha: {DateTime.Now}");\n}\n\n\nEl parámetro append: true significa que añadimos datos al final del archivo, sin borrar lo existente.
Trabajo con directorios: creando y eliminando carpetas
\n\nLa clase Directory te permite gestionar carpetas: crear, mover, eliminar y obtener su contenido.
// Crear carpeta\nDirectory.CreateDirectory(@"C:\\MyApp\\Logs");\n\n// Verificar si existe\nif (Directory.Exists(@"C:\\MyApp\\Logs"))\n{\n Console.WriteLine("La carpeta existe");\n}\n\n// Obtener todos los archivos .txt\nstring[] txtFiles = Directory.GetFiles(@"C:\\MyApp\\Logs", "*.txt");\n\n// Eliminar carpeta (solo si está vacía)\nDirectory.Delete(@"C:\\MyApp\\Temp");\n\n// Eliminar carpeta con todo su contenido\nDirectory.Delete(@"C:\\MyApp\\OldData", recursive: true);\n\n\nManejo de errores: qué hacer cuando algo sale mal
\n\nTrabajar con el sistema de archivos siempre conlleva riesgos: el archivo puede estar bloqueado, la ruta puede ser incorrecta o no tener permisos. Por eso, el manejo de excepciones es obligatorio.
\n\ntry\n{\n string[] lines = File.ReadAllLines(@"C:\\important\\data.txt");\n}\ncatch (FileNotFoundException ex)\n{\n Console.WriteLine($"Archivo no encontrado: {ex.FileName}");\n}\ncatch (UnauthorizedAccessException)\n{\n Console.WriteLine("No hay permisos para leer el archivo");\n}\ncatch (IOException ex)\n{\n Console.WriteLine($"Error de E/S: {ex.Message}");\n}\n\n\nConclusión: de novato a experto en archivos
\n\nHemos recorrido el camino desde File.ReadAllText hasta FileStream y Directory. Ahora sabes:
- \n
- Cuándo usar
Filey cuándoFileInfo\n - Cómo leer archivos de diferentes tamaños sin perder rendimiento \n
- Cómo escribir datos de forma segura usando modos de apertura \n
- Cómo gestionar carpetas y manejar errores \n
La práctica es clave. Abre tu IDE favorito, crea un par de archivos de prueba y experimenta con los ejemplos de este artículo. ¡Pronto trabajar con archivos en C# se convertirá en tu segunda naturaleza!