1. Lectura de atributos básicos: BasicFileAttributes
Cuando hablamos de un archivo o carpeta, no nos referimos solo a su nombre o tamaño. Cada archivo tiene «pasaporte», un conjunto de atributos que contiene:
- Hora de creación
- Hora de la última modificación
- Hora del último acceso
- Tamaño
- Permisos de acceso (quién puede leer, escribir, ejecutar)
- Información del propietario (en Unix)
- Indicadores «oculto», «solo lectura» y otros
En Java hay una API cómoda y potente en el paquete java.nio.file.attribute para trabajar con estos atributos. No hace falta escribir código dependiente de la plataforma: todo lo necesario está en la biblioteca estándar.
Para empezar — importamos las clases necesarias:
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.IOException;
¿Cómo obtener los atributos básicos de un archivo?
Usamos el método Files.readAttributes:
Path path = Paths.get("example.txt");
try {
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("Creado: " + attrs.creationTime());
System.out.println("Modificado: " + attrs.lastModifiedTime());
System.out.println("Último acceso: " + attrs.lastAccessTime());
System.out.println("Tamaño: " + attrs.size());
System.out.println("¿Es un directorio? " + attrs.isDirectory());
System.out.println("¿Es un archivo? " + attrs.isRegularFile());
System.out.println("¿Es un enlace simbólico? " + attrs.isSymbolicLink());
} catch (IOException e) {
System.out.println("Error al leer atributos: " + e.getMessage());
}
Imagine que es inspector y viene a revisar un piso. No solo mira si hay puerta (el archivo existe), sino que también pregunta a los inquilinos: «¿Cuándo se construyó el edificio? ¿Cuándo fue la última reforma? ¿Quién es el propietario?».
Resumen de las propiedades de BasicFileAttributes
| Propiedad | ¿Qué devuelve? |
|---|---|
|
Fecha y hora de creación del archivo/carpeta |
|
Fecha y hora de la última modificación |
|
Fecha y hora del último acceso |
|
Tamaño del archivo (en bytes) |
|
¿Es un directorio? |
|
¿Es un archivo regular? |
|
¿Es un enlace simbólico? |
2. Atributos avanzados: POSIX y DOS
Atributos POSIX (Linux, macOS y otros sistemas tipo Unix)
Si trabaja en un sistema Unix, puede obtener información ampliada: permisos, propietario, grupo.
try {
PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
System.out.println("Propietario: " + posixAttrs.owner().getName());
System.out.println("Grupo: " + posixAttrs.group().getName());
System.out.println("Permisos: " + PosixFilePermissions.toString(posixAttrs.permissions()));
} catch (UnsupportedOperationException e) {
System.out.println("Los atributos POSIX no están soportados en este SO.");
} catch (IOException e) {
System.out.println("Error al leer atributos POSIX: " + e.getMessage());
}
Nota: En Windows, este código lanzará UnsupportedOperationException — es normal.
Atributos DOS (Windows)
En Windows se puede trabajar con las marcas «solo lectura», «oculto», «de archivo» y «de sistema»:
try {
DosFileAttributes dosAttrs = Files.readAttributes(path, DosFileAttributes.class);
System.out.println("Oculto: " + dosAttrs.isHidden());
System.out.println("Solo lectura: " + dosAttrs.isReadOnly());
System.out.println("De sistema: " + dosAttrs.isSystem());
System.out.println("De archivo: " + dosAttrs.isArchive());
} catch (UnsupportedOperationException e) {
System.out.println("Los atributos DOS no están soportados en este SO.");
} catch (IOException e) {
System.out.println("Error al leer atributos DOS: " + e.getMessage());
}
3. Modificación de atributos de archivos
Leer pasaportes ajenos es una cosa, ¡cambiar la fecha de nacimiento o el apellido es otra! En Java podemos modificar atributos de archivos (por supuesto, con los permisos necesarios).
Cambiar la hora de la última modificación
import java.nio.file.attribute.FileTime;
Path file = Paths.get("example.txt");
try {
FileTime newTime = FileTime.fromMillis(System.currentTimeMillis() - 24 * 60 * 60 * 1000); // menos 1 día
Files.setLastModifiedTime(file, newTime);
System.out.println("¡La hora de la última modificación ha sido cambiada!");
} catch (IOException e) {
System.out.println("Error al cambiar la hora: " + e.getMessage());
}
Cambiar permisos (POSIX)
¡Solo para sistemas Unix! Por ejemplo, hacer que el archivo sea ejecutable para todos:
try {
Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-xr-x");
Files.setPosixFilePermissions(file, perms);
System.out.println("¡Permisos cambiados!");
} catch (UnsupportedOperationException e) {
System.out.println("Los permisos POSIX no están soportados en este SO.");
} catch (IOException e) {
System.out.println("Error al cambiar los permisos: " + e.getMessage());
}
Explicación de la cadena "rwxr-xr-x":
- r — read (lectura)
- w — write (escritura)
- x — execute (ejecución)
- El primer bloque de 3 caracteres es el propietario, el segundo es el grupo y el tercero los demás.
Cambiar el estado oculto/solo lectura (atributos DOS, Windows)
Hacer que el archivo sea oculto:
try {
Files.setAttribute(file, "dos:hidden", true);
System.out.println("¡El archivo se ha vuelto oculto (Windows)!");
} catch (UnsupportedOperationException e) {
System.out.println("Los atributos DOS no están soportados en este SO.");
} catch (IOException e) {
System.out.println("Error al cambiar el atributo: " + e.getMessage());
}
Hacer que el archivo sea «solo lectura»:
try {
Files.setAttribute(file, "dos:readonly", true);
System.out.println("¡El archivo ahora es de solo lectura (Windows)!");
} catch (UnsupportedOperationException e) {
System.out.println("Los atributos DOS no están soportados en este SO.");
} catch (IOException e) {
System.out.println("Error al cambiar el atributo: " + e.getMessage());
}
4. Comprobación de permisos de acceso
A veces es importante comprobar rápidamente si se puede abrir un archivo para lectura, escritura o ejecución:
Path file = Paths.get("example.txt");
System.out.println("Lectura permitida: " + Files.isReadable(file));
System.out.println("Escritura permitida: " + Files.isWritable(file));
System.out.println("Ejecución permitida: " + Files.isExecutable(file));
Esto funciona igual en todas las plataformas, aunque el comportamiento real depende del SO y de la configuración de seguridad.
5. Práctica: mostrar información detallada sobre un archivo
Escribamos un mini-programa que, dado el camino a un archivo, muestre la mayor cantidad de información posible e intente cambiar algunos atributos.
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.Set;
import java.io.IOException;
public class FileAttributesDemo {
public static void main(String[] args) throws IOException {
Path path = Paths.get("example.txt");
if (!Files.exists(path)) {
System.out.println("¡Archivo no encontrado!");
return;
}
// Atributos básicos
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("Nombre: " + path.getFileName());
System.out.println("Ruta: " + path.toAbsolutePath());
System.out.println("Tamaño: " + attrs.size() + " bytes");
System.out.println("Creado: " + attrs.creationTime());
System.out.println("Modificado: " + attrs.lastModifiedTime());
System.out.println("Último acceso: " + attrs.lastAccessTime());
System.out.println("¿Es un directorio? " + attrs.isDirectory());
System.out.println("¿Es un archivo? " + attrs.isRegularFile());
// Comprobación de permisos de acceso
System.out.println("Lectura permitida: " + Files.isReadable(path));
System.out.println("Escritura permitida: " + Files.isWritable(path));
System.out.println("Ejecución permitida: " + Files.isExecutable(path));
// Intentemos cambiar la hora de modificación
FileTime now = FileTime.fromMillis(System.currentTimeMillis());
Files.setLastModifiedTime(path, now);
System.out.println("¡Hora de la última modificación actualizada!");
// Intentemos hacer el archivo oculto (si se soporta)
try {
Files.setAttribute(path, "dos:hidden", true);
System.out.println("El archivo se ha vuelto oculto (si el SO lo soporta).");
} catch (UnsupportedOperationException e) {
System.out.println("Los archivos ocultos no están soportados en este SO.");
}
// Intentemos mostrar los permisos POSIX (si se soporta)
try {
PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
System.out.println("Propietario: " + posixAttrs.owner().getName());
System.out.println("Permisos: " + PosixFilePermissions.toString(posixAttrs.permissions()));
} catch (UnsupportedOperationException e) {
System.out.println("Los atributos POSIX no están soportados en este SO.");
}
}
}
6. Matices útiles
Diferencias multiplataforma y consejos
- ¡No todos los atributos están disponibles en todos los SO! En Windows no hay permisos POSIX, y en Linux no hay atributos DOS.
- ¡Use siempre try-catch! Los métodos pueden lanzar UnsupportedOperationException o IOException.
- Los permisos no son siempre solo «rwx». En Windows el modelo de permisos es diferente; «solo lectura» puede estar definido por la política de seguridad del SO.
- Los archivos ocultos son un concepto relativo. En Unix un archivo está oculto si el nombre empieza por un punto (.hidden); en Windows — si se establece el atributo dos:hidden.
Tabla: qué atributos están disponibles dónde
| Atributo | Windows (dos:*) | Linux/macOS (posix:*) |
|---|---|---|
| Hora de creación | + | + |
| Hora de la última modificación | + | + |
| Hora del último acceso | + | + |
| Archivo oculto | + | Solo nombre con punto |
| Solo lectura | + | + |
| Permisos (rwx) | - | + |
| Propietario, grupo | - | + |
| De archivo, de sistema | + | - |
7. Errores típicos al trabajar con atributos de archivos
Error nº 1: intentar leer o modificar atributos POSIX en Windows. En Windows obtendrá UnsupportedOperationException. Maneje siempre esta excepción si escribe código multiplataforma.
Error nº 2: cambiar la hora de modificación de un archivo que está abierto por otro proceso. En algunos sistemas el archivo puede estar bloqueado y la operación fallará.
Error nº 3: esperar que la operación «ocultar archivo» funcione igual en todos los SO. En Unix está oculto un archivo cuyo nombre comienza con un punto (.gitignore), y en Windows si se establece el atributo dos:hidden. No confunda estos enfoques.
Error nº 4: omitir la comprobación de existencia del archivo antes de la operación. Si el archivo no existe, obtendrá NoSuchFileException al intentar obtener o modificar sus atributos.
Error nº 5: no comprobar los permisos de acceso. Si el usuario no tiene permisos para cambiar atributos, la operación fallará. Antes de los cambios, compruebe Files.isWritable(path).
GO TO FULL VERSION