1. Introducción
Si las clases estáticas como File y Directory son como una navaja suiza universal: siempre a mano, resuelven rápido la tarea pero sin ligarse a un objeto concreto, entonces FileInfo y DirectoryInfo son herramientas personalizadas: se crean para un archivo o carpeta específicos, «conocen» bastante sobre ellos y permiten trabajar de forma más cómoda y flexible, especialmente cuando haces múltiples operaciones sobre el mismo objeto.
Las clases de instancia almacenan detalles sobre un objeto concreto del sistema de archivos; tras la primera carga de propiedades no hace falta volver a consultar el sistema de archivos por la misma información (a menos que el objeto quede desactualizado).
- FileInfo — para trabajar con un archivo concreto.
- DirectoryInfo — para trabajar con un directorio (carpeta) concreto.
Contienen propiedades y métodos que permiten obtener información detallada (tamaño, fecha de creación, extensión, atributos disponibles) y realizar acciones sobre el archivo/carpeta: copiar, eliminar, mover, etc.
Cómo están organizadas FileInfo y DirectoryInfo
Ambas clases heredan de una clase abstracta común FileSystemInfo, lo que permite escribir código que trabaje con archivos y carpetas de forma uniforme.
System.Object
|
System.MarshalByRefObject
|
System.IO.FileSystemInfo (clase abstracta)
| |
FileInfo DirectoryInfo
¿Cuándo usar las clases de instancia?
- Si necesitas mucha información sobre un archivo/carpeta (tamaño, fecha de modificación, extensión, atributos, etc.) y esos datos se usan más de una vez.
- Si quieres iterar todos los archivos/carpetas de un directorio y tratar cada objeto como una instancia «viva».
- Para optimizar cuando es importante no consultar de más el sistema de archivos (caché de información).
- Para un código más orientado a objetos (backups, biblioteca multimedia, gestor de archivos, etc.).
Cómo crear una instancia de FileInfo o DirectoryInfo
using System.IO;
// Creación de un objeto FileInfo para un archivo existente (¡o no!):
var fileInfo = new FileInfo("notes.txt");
// Creación de un objeto DirectoryInfo para una carpeta:
var dirInfo = new DirectoryInfo(@"C:\Projects");
// ¡Puedes usar rutas relativas o absolutas!
Importante: crear un objeto FileInfo o DirectoryInfo NO crea el archivo/carpeta en el sistema de archivos. Es solo una descripción (un enlace).
2. Trabajo con FileInfo
Vamos a repasar las propiedades y métodos principales de esta clase. Aquí tienes una chuleta:
| Propiedad/método | ¿Qué devuelve? | Ejemplo de uso |
|---|---|---|
|
Nombre del archivo | |
|
Ruta completa | |
|
Tamaño del archivo en bytes | |
|
Directorio padre (DirectoryInfo) | |
|
¿Existe realmente el archivo? | |
|
Extensión del archivo (.txt) | |
|
Fecha de creación | |
|
Fecha de la última modificación | |
|
¿Sólo lectura? | |
| Métodos | ||
|
Copiar el archivo | |
|
Eliminar el archivo | |
|
Mover el archivo | |
|
Abrir un stream para lectura | |
|
Abrir un stream para escritura | |
Ejemplo: Información sobre un archivo
Vamos a añadir un pequeño módulo que obtiene información detallada de un archivo usando FileInfo.
Console.WriteLine("Introduce el nombre del archivo:");
string fileName = Console.ReadLine();
var file = new FileInfo(fileName);
if (file.Exists)
{
Console.WriteLine($"Nombre del archivo: {file.Name}");
Console.WriteLine($"Ruta: {file.FullName}");
Console.WriteLine($"Tamaño: {file.Length} bytes");
Console.WriteLine($"Extensión: {file.Extension}");
Console.WriteLine($"Fecha de creación: {file.CreationTime}");
Console.WriteLine($"Última modificación: {file.LastWriteTime}");
// Adicional: mostrar el directorio padre
Console.WriteLine($"Carpeta padre: {file.DirectoryName}");
}
else
{
Console.WriteLine("Archivo no encontrado.");
}
Fíjate: no leemos el contenido del archivo, solo obtenemos metainformación.
Práctica: Copiar y eliminar un archivo
// ... Dentro del método principal después de mostrar la info del archivo:
Console.WriteLine("Introduce la ruta para la copia del archivo:");
string copyPath = Console.ReadLine();
try
{
file.CopyTo(copyPath);
Console.WriteLine($"Archivo copiado con éxito a {copyPath}");
}
catch (IOException ex)
{
Console.WriteLine($"No se pudo copiar el archivo: {ex.Message}");
}
// Ahora eliminamos la copia
Console.WriteLine("¿Eliminar la copia del archivo? (y/n):");
if (Console.ReadLine().Trim().ToLower() == "y")
{
var copyFile = new FileInfo(copyPath);
if (copyFile.Exists)
{
copyFile.Delete();
Console.WriteLine("Copia eliminada.");
}
}
3. Trabajo con DirectoryInfo
Veamos qué nos ofrece DirectoryInfo:
| Propiedad/método | ¿Qué devuelve? | Ejemplo de uso |
|---|---|---|
|
Nombre de la carpeta | |
|
Ruta completa | |
|
Carpeta padre (DirectoryInfo) | |
|
¿Existe la carpeta? | |
|
Fecha de creación | |
|
Fecha de modificación | |
| Métodos | ||
|
Crear la carpeta | |
|
Eliminar la carpeta | |
|
Matriz de archivos (array de FileInfo) | |
|
Matriz de subcarpetas (array de DirectoryInfo) | |
|
Enumeración de archivos (devuelve IEnumerable<FileInfo>, modo diferido) | |
|
Mover la carpeta | |
Ejemplo: Recorrer archivos y carpetas
Console.WriteLine("Introduce la ruta de la carpeta:");
string path = Console.ReadLine();
var dir = new DirectoryInfo(path);
if (!dir.Exists)
{
Console.WriteLine("¡Carpeta no encontrada!");
return;
}
Console.WriteLine("\n--- Archivos ---");
foreach (var file in dir.GetFiles())
{
Console.WriteLine($"{file.Name} ({file.Length} bytes)");
}
Console.WriteLine("\n--- Subcarpetas ---");
foreach (var subDir in dir.GetDirectories())
{
Console.WriteLine(subDir.Name);
}
4. Matices útiles
Métodos estáticos vs clases de instancia
¿Cuándo usar cada enfoque? Si haces una acción rápida «one-off» —por ejemplo, File.Exists(path) o File.ReadAllText(path)— los métodos estáticos suelen ser la mejor opción. Son más simples y un poco más rápidos por la mínima sobrecarga.
Si, en cambio, quieres obtener mucha información sobre un archivo o carpeta, realizar operaciones repetidas sobre ese objeto, o simplemente escribes en estilo OOP, es mejor usar las instancias FileInfo y DirectoryInfo.
Curiosamente, ambos enfoques usan llamadas de bajo nivel similares «bajo el capó». Pero las clases de instancia hacen caché de algunas propiedades (tamaño, fecha, atributos), reduciendo el número de accesos al sistema de archivos —muy útil al procesar muchos archivos.
Un poco sobre fechas y horas
Las propiedades CreationTime, LastWriteTime, LastAccessTime devuelven valores del tipo DateTime.
Console.WriteLine($"Archivo creado: {file.CreationTime:yyyy-MM-dd HH:mm:ss}");
Console.WriteLine($"Última modificación: {file.LastWriteTime:yyyy-MM-dd HH:mm:ss}");
Si el archivo o carpeta se modificó en disco después de que obtuviste el objeto FileInfo o DirectoryInfo, la información en caché puede quedar obsoleta. Para actualizarla, llama file.Refresh().
Consejos y observaciones prácticas
- Las clases de instancia son útiles cuando construyes una capa sobre el sistema de archivos: backups, biblioteca multimedia, indexador.
- Funcionan genial con LINQ: puedes filtrar por tamaño, fecha o extensión y ejecutar operaciones sobre los objetos seleccionados.
- Para operaciones masivas es preferible EnumerateFiles() y EnumerateDirectories() en lugar de GetFiles()/GetDirectories() —la enumeración perezosa ahorra memoria y acelera el inicio del procesamiento.
Comparación del enfoque estático y el de instancias
| Métodos estáticos | Clases de instancia | |
|---|---|---|
| Sintaxis | |
|
| Caché | No | Sí |
| Mucha información | Hay que llamar muchos métodos | Está en el objeto |
| Estilo OOP | No | Sí |
| Operaciones masivas | Incómodo | Cómodo |
| Trabajo con streams | Sí | Sí |
Actualizar información y objetos
Los objetos FileInfo/DirectoryInfo almacenan en caché los valores tras el primer acceso a las propiedades. Si el objeto (archivo o carpeta) cambió en disco después de crear la instancia, para actualizar la información llama al método .Refresh().
var file = new FileInfo("notes.txt");
long oldSize = file.Length;
// En este tiempo alguien (o tú mismo) cambia el archivo desde fuera del programa
file.Refresh();
long newSize = file.Length;
Esto no es muy frecuente, pero si tu programa observa el sistema de archivos, el mecanismo es importante.
5. Errores típicos al trabajar con clases de instancia
Falsa creencia: si creas un objeto new FileInfo("file.txt"), ya existe el archivo. En realidad no: el archivo aparece solo después de escribir explícitamente o llamar a Create().
Intentar obtener propiedades de un archivo que no existe: algunas propiedades devolverán valores por defecto (por ejemplo, tamaño 0), pero intentar abrir un stream de lectura lanzará una excepción.
Con carpetas pasa lo mismo: crear DirectoryInfo no garantiza que la carpeta exista en disco hasta que llames a Create() o hasta que realmente aparezca.
GO TO FULL VERSION