CodeGym /Cursos /JAVA 25 SELF /Obtención y modificación de atributos de archivos

Obtención y modificación de atributos de archivos

JAVA 25 SELF
Nivel 39 , Lección 4
Disponible

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?
creationTime()
Fecha y hora de creación del archivo/carpeta
lastModifiedTime()
Fecha y hora de la última modificación
lastAccessTime()
Fecha y hora del último acceso
size()
Tamaño del archivo (en bytes)
isDirectory()
¿Es un directorio?
isRegularFile()
¿Es un archivo regular?
isSymbolicLink()
¿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).

1
Tarea
JAVA 25 SELF, nivel 39, lección 4
Bloqueada
Experto en seguridad: auditoría de permisos de acceso
Experto en seguridad: auditoría de permisos de acceso
1
Tarea
JAVA 25 SELF, nivel 39, lección 4
Bloqueada
Encargado del archivo: actualización de la marca de tiempo
Encargado del archivo: actualización de la marca de tiempo
1
Cuestionario/control
Trabajo con el sistema de archivos, nivel 39, lección 4
No disponible
Trabajo con el sistema de archivos
Trabajo con el sistema de archivos
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION