Menú de navegaciónMenú
Categorías

La mejor forma de Aprender Programación online y en español www.campusmvp.es

?id=a3e627ca-e1d1-4af9-8a3e-7fe12ceb7fb2

Java: cómo listar, filtrar y obtener información de carpetas y archivos

Una tarea común y básica que necesitamos hacer en cualquier programa es acceder a la información de los archivos y carpetas del sistema de archivos local. Desde algo tan básico como ver el nombre y el tamaño de un archivo hasta listar los contenidos de cualquier carpeta.

En Java esto es muy fácil de conseguir gracias a la clase java.io.File. Esta clase nos permite obtener información sobre cualquier elemento del sistema de archivos.

Para utilizarla solo tenemos que importarla en la cabecera de nuestro programa:

import java.io.File;

Y podremos utilizarla en nuestra aplicación.

Para obtener información sobre un archivo o carpeta basta con usar su constructor pasándole la ruta de éste. Así:

String sCarpAct = System.getProperty("user.dir");
File carpeta = new File(sCarpAct);

En la primera línea obtenemos la carpeta actual desde la que se está ejecutando el código, y utilizamos la clase File para obtener información sobre la misma. A este constructor le podemos pasar una ruta absoluta o relativa en el sistema de archivos.

La clase File sirve para representar a un archivo o carpeta y ofrece propiedades y métodos que nos permiten acceder a sus datos y realizar operaciones sobre ellos, como renombrar, eliminar, crear carpetas, listar sus contenidos, etc... Lo que podamos hacer con ella dependerá de los permisos que tengamos sobre el archivo o carpeta en cuestión. 

Algunos de los métodos de File mostrados por la ayuda contextual de un editor

Algunos de estos métodos son:

  • canExecute(): devuelve un true o false en función de si el archivo es ejecutable o no.
  • canRead(): si tienes acceso de lectura o no
  • canWrite(): si puedes escribir en él o no
  • createNewFile(): crea un nuevo archivo vacío con el nombre que se le indique.
  • delete(): borra el archivo o directorio
  • exists(): determina si el archivo representado por File en la ruta que le hayamos pasado existe o no.
  • getName(): el nombre del archivo o carpeta
  • getParent(): devuelve una cadena con la ruta de la carpeta "madre" del archivo o carpeta actuales.
  • isDirectory(): indica si el objeto actual representa a una carpeta o no
  • isFile():  indica si el objeto actual representa a un archivo
  • isHidden(): si es un elemento oculto en el sistema de archivos
  • length(): el tamaño del archivo en bytes. Si no existe o no tienes permiso devuelve un 0. En el caso de carpetas en Linux/Mac con sistema de archivos ext3/ext4 siempre devuelve 4096 ya que este es el tamaño de un bloque en Linux y es el mínimo que puede ocupar cualquier enlace en disco, como una carpeta (4KB).
  • list(): los nombres de los archivos y carpetas hijos de una carpeta.
  • listFiles(): como el anterior pero devolviendo objetos File para cada archivo o carpeta.
  • mkdir(): crea una carpeta
  • renameTo(): renombra el archivo o carpeta

Con todo esto se pueden hacer muchas cosas. Consúltalos todos en la documentación con el enlace anterior.

Vamos a ver un ejemplo de cómo listar todos los archivos de una carpeta usando varios de estos métodos:

File carpeta = new File(sCarpAct);
String[] listado = carpeta.list();
if (listado == null || listado.length == 0) {
    System.out.println("No hay elementos dentro de la carpeta actual");
    return;
}
else {
    for (int i=0; i< listado.length; i++) {
        System.out.println(listado[i]);
    }
}

Lo que se hace en este fragmento es:

  1. Se crea un nuevo objeto File para representar la carpeta que nos interesa.
  2. Con el método list() obtenemos los nombres de todos sus hijos
  3. Si no devuelve nada o la longitud es 0 mostramos un mensaje de que no hay elementos en la carpeta actual (también podríamos haber comprobado si es una carpeta o no con isDirectory())
  4. En la otra rama del condicional recorremos en un bucle sencillo todos los nombres de elementos hijo mostrando sus nombres cada uno en una línea en la consola.

Veríamos algo como esto:

Está bien para replicar el comando ls (Linux, Mac) o dir (Windows) básico de la línea de comandos, pero si queremos más información no nos va a servir de mucho.

Podemos mejorarlo utilizando el método listFiles() que nos devuelve objetos File y por lo tanto podemos mostrar más información de cada uno sin tener que crearlos explícitamente, así:

File[] archivos = carpeta.listFiles();
if (archivos == null || archivos.length == 0) {
    System.out.println("No hay elementos dentro de la carpeta actual");
    return;
}
else {
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
    for (int i=0; i< archivos.length; i++) {
        File archivo = archivos[i];
        System.out.println(String.format("%s (%s) - %d - %s",
                archivo.getName(),
                archivo.isDirectory() ? "Carpeta" : "Archivo",
                archivo.length(),
                sdf.format(archivo.lastModified())
                ));
    }
}

En este caso el código es parecido, pero podemos utilizar los métodos que hemos visto para mostrar más información sobre cada elemento. En este caso mostramos su nombre, si es un directorio o un archivo, su tamaño y la fecha de última modificación. Para mostrar la fecha en un formato adecuado utilizo la clase SimpleDateFormater del paquete java.text.SimpleDateFormat.

Bien. Pero, ¿qué pasa si no queremos mostrar todos los archivos, sino sólo los que cumplan con ciertas condiciones?

Para eso podemos utilizar un filtro. Los filtros son clases que implementan la interfaz FilenameFilter (si solo queremos filtrar por el nombre) o FileFilter (si queremos usar objetos File para el filtrado). Esta interfaz lo único que define es un método accept() que, en su sobrecarga más simple, toma como parámetro el archivo a filtrar y debe devolver true o false en función de si el archivo pasa el filtro o no.

Por ejemplo, vamos a filtrar los elementos de nuestra carpeta para que devuelve únicamente archivos, pero no carpetas. Es una condición sencilla, pero lógicamente podríamos aplicar cualquier regla compleja que nos interesase en función de las propiedades disponibles de cada elemento (su nombre, tamaño, permisos... o una combinación de varios de ellos).

Veamos cómo hacerlo.

En primer lugar vamos a definir el filtro:

FileFilter filtro = new FileFilter() {
    @Override
    public boolean accept(File arch) {
        return arch.isFile();
    }
};

En este caso, por brevedad, he usado un literal con el constructor para crear el objeto e implementar el método accept(), pero podría haber creado la clase de la manera más convencional usando implements para implementar la interfaz, etc.. La forma es lo de menos. Lo único que hace es llamar al método isFIle() de cada archivo o carpeta para devolver true solo en caso de que sean archivos. De este modo solamente se obtendrán archivos y ninguna carpeta tras realizar el filtrado.

Ahora utilizarlo es tan sencillo como pasar el nuevo objeto de filtro al método listFiles(), así:

archivos = carpeta.listFiles(filtro);

if (archivos == null || archivos.length == 0) {
    System.out.println("No hay elementos dentro de la carpeta actual");
    return;
}
else {
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
    for (int i=0; i< archivos.length; i++) {
        File archivo = archivos[i];
        System.out.println(String.format("%s (%s) - %d - %s", 
                        archivo.getName(),
                        archivo.isDirectory() ? "Carpeta" : "Archivo",
                        archivo.length(),
                        sdf.format(archivo.lastModified())
                ));
    }
}

Tan solo cambia la primera línea. El resto es como en el ejemplo anterior, solo que en este caso veremos en la consola únicamente los archivos y no los directorios gracias al filtro que hemos aplicado.

Como ves el uso de esta clase es extremadamente sencillo.

Te dejo todo el código de ejemplo en este repl.it, embebido a continuación. Pulsa el triángulo de la parte de arriba para ejecutarlo directamente en el navegador y ver sus resultados:

Nota: si te preguntas cómo hago lo de mostrar colores en la consola, lee este otro artículo.

¡Espero que te resulte útil!

Fecha de publicación:
José Manuel Alarcón Fundador de campusMVP, es ingeniero industrial y especialista en consultoría de empresa. Ha escrito diversos libros, habiendo publicado hasta la fecha cientos de artículos sobre informática e ingeniería en publicaciones especializadas. Microsoft lo ha reconocido como MVP (Most Valuable Professional) en desarrollo web desde el año 2004 hasta la actualidad. Puedes seguirlo en Twitter en @jm_alarcon o leer sus blog técnico o personal. Ver todos los posts de José Manuel Alarcón
Archivado en: Lenguajes y plataformas

Boletín campusMVP.es

Solo cosas útiles. Una vez al mes.

🚀 Únete a miles de desarrolladores

DATE DE ALTA

x No me interesa | x Ya soy suscriptor

La mejor formación online para desarrolladores como tú

Comentarios (18) -

he usado el codigo para mostrar el contenido de una carpeta, pero me muestran archivos que no existen

este es el resultado
.DS_Store
.zip
.zipc.zipa.zipr.zipp.zipe.zipt.zipa.zip .zips.zipi.zipn.zip .zipt.zipí.zipt.zipu.zipl.zipo.zip
.zipn.zipe.zipw.zip .zipO.zipr.zipd.zipn.zipe.zipr.zip
.zipn.zipe.zipw.zip .zipo.zipr.zipd.zipn.zipe.zipr.zip
.zipn.zipu.zipe.zipv.zipa.zip .zipc.zipa.zipr.zipp.zipe.zipt.zipa.zip

el archivo .DS_Store es el único que existe dentro de la carpeta, los otros no, esto es un error

Responder

José Manuel Alarcón
José Manuel Alarcón

Hola:

No tengo Mac así que no sé muy bien qué tipo de archivos suele ocultar en sus carpetas, pero si salen esos archivos es que están ahí, aunque seguramente estarán ocultos. Como explico en el post, listFiles() muestra todos los archivos. Esto incluye a los ocultos o los del sistema.

Si no quieres que te salgan los archivos ocultos lo tienes fácil: en el filtro utiliza el método isHidden() para determinar si está oculto o no y entonces filtrarlo para no mostrarlo.

Saludos.

Responder

Muchas gracias José Manuel Alarcón por tu pronta respuesta, no había pensado en eso en verdad, me ha servido de mucha ayuda que me ayudaras con tu comentario, me permite pasar página con este tema y seguir estudiando.

Saludos y mucha suerte en todo

Responder

Probablemente un resto de vírus en esa carpeta o una carpeta del sistema.

Responder

como puedo mostrar solo un tipo de archivos ejemplo solo xml

Responder

José Manuel Alarcón
José Manuel Alarcón

Pues muy sencillo si lees con calma la explicación. Igual que en el ejemplo se filtran los resultados, por ejemplo, solo para mostrar archivos y no carpetas, pues puedes hacer lo mismo para filtrar sólo archivos con ciertas extensiones a partir de su nombre (con getName). Es directo.

Saludos.

Responder

Eduardo Reyes
Eduardo Reyes

Es un grave peligro, ya que como queden datos de caracter personal en nuestras memorias o dispositivos, cualquiera podrá acceder a ellos

Responder

José Manuel Alarcón
José Manuel Alarcón

Hombre Eduardo, será un peligro si te dedicas a instalar o ejecutar cualquier cosa que te llegue. Acceder al sistema de archivos es una funcionalidad básica de cualquier programa y tiene que poder hacerlo. ¿no Crees?

La gestión de datos personales, contraseñas y demás debería hacerse de manera consciente u controlada, almacenarlos en lugares seguros (como discos encriptados) y controlar el acceso con los permisos del sistema y con otras características como la protección ante Cryptolockers que tiene Windows. Sólo de ese modo puedes garantizar la seguridad, pero no tiene nada que ver con que los programas pueden leer y escribir a disco o a memoria.

Saludos.

Responder

Muchas gracias por todos los consejos!!! Muy claro y explicado de manera amena!

Responder

Jairo Rodriguez
Jairo Rodriguez

Se puede saber que propiedad o atributo de las carpetas o archivos acceden lo métodos para validar los permisos?
Tengo un problema con una aplicación, ya que a una carpeta se le dan permisos completos, pero el método canWrite me retorna false, esto en un ambiente donde supongo tienen permisos por usuarios et...
No conozco el tema de infraestructura, entonces me gustaría saber con que usuario java accede al sistema de archivos, o si hay un permiso especial en el SO para aplicativos.

Responder

José Manuel Alarcón
José Manuel Alarcón

Hola Jairo:

El tema de los permisos depende de cómo los implemente el sistema operativo, del usuario y grupo(s) bajo los que se ejecute el proceso actual, de los permisos propios de Java y también del entorno en el que se ejecute (por ejemplo, si se ejecuta en Tomcat o un servidor de aplicaciones similar).

Si nos referimos tan solo a un programa ejecutado por ti como usuario, los permisos son los mismos que los de tu usuario, que es el que ejecuta el proceso. Ahora bien, dependiendo del sistema operativo, los permisos funcionan de diferente manera. Por ejemplo en Linux podrías ejecutar un proceso de modo que aunque el usuario y su(s) grupo(s) tengan permisos pero el proceso no los tenga a pesar de ello. O en Windows también podría darse el caso de que por los requisitos específicos del archivo necesitases elevación aunque por defecto el proceso tenga permisos.

Así que vete a saber. Dependerá de muchas cosas. No obstante, si lo estás lanzando como un proceso normal accediendo a archivos para los que tienes permisos debería funcionarte sin problemas, como se ve en el ejemplo.

Deberías siempre envolver el acceso en un try-catch para evitar posibles problemas, y además puedes comprobar si tienes los permisos adecuados antes de hacer una operación valiéndote de los métodos canRead() y canWrite() de la clase File que menciono en el artículo.

Saludos.

Responder

Muy bien explicado.
Si estoy buscando en una carpeta que a su vez tiene carpetas y quiero ver los ficheros de esas subcarpetas?
Como entro dentro de esas subcarpetas y buscar los ficheros?

Responder

José Manuel Alarcón
José Manuel Alarcón

Hola Pablo:

Una palabra: recursividad. O sea, haces lo mismo con la misma función para cada subcarpeta, y así sucesivamente.

Saludos.

Responder

hola buenas tardes me gusto mucho tu tutorial me a serbido mucho
estoy haciendo lo mismo pero qe me mestre las carpaetas en c:\\ ,
ya tengo para que me muestre solo las carpetas que no estan ocultas,
ahora quiero q solo me muestre ciertas carpetas por ejemplo qe me muestre documentro, descargas, imagenes .
como podria hacerlo ?

gracias
saludos

Responder

buenos dias, tengo dudas respecto obtencion del archivo o ruta, pues en el framework que uso me muestra bien la ruta al ejecutar, en windows funciona, en linux funciona perso solo se lo abro por medio de la terminal (java -jar archivo.jar), pero si le doy doble click marca error de que no se encontro la ruta o archivo.

añadi un mensaje para que me muestre la ruta que esa tomando y en linux solo con doble click siempre muestra la ruta desde ( /home ), hay alguna manera de que me muestre la ruta desde donde se ejecuta el jar?

Responder

Hola,quiero filtrar el archivo que contenga el nombre que le paso y que tenga la fecha actual del sistema por ejemplo quiero el de hoy que es fecha 20210714(archivo_a_20210714.txt) y también el archivo fecha 20210714 (archivo_b_20210714.txt) pero con nombre diferente. a continuación detallo como están los archivos

archivo_a_20210712.txt
archivo_a_20210713.txt
archivo_a_20210714.txt

otro archivo

archivo_b_20210712.txt
archivo_b_20210713.txt
archivo_b_20210714.txt

tengo esto pero solo me filtra por nombre (la cadena nombre se la mando asi desde otra clase, listaArchivos = dir.list(new Filtro("archivo_a_"));) y extencion, no le pongo la fecha ya que esta cambia depende del dia.

¿como obtengo los archivos que tengan la fecha de hoy?

public class Filtro implements FilenameFilter {

    String nombre;
    public Filtro(String nombre){
        this.nombre=nombre;
    }
    public boolean accept(File dir, String name){

        if(name.startsWith(nombre) && name.endsWith(".txt")){
            return true;
        } else {
            return false;
        }
    }

}

Responder

Jorge Luis
Jorge Luis

Hola, yo obtengo ya cierto datos de una carpeta, pero quiero leer subcarpetas y sus archivos que estan adentro, alguna idea?

Responder

José Manuel Alarcón
José Manuel Alarcón

Hola:

Hazlo con recursividad. Crea una función que se llame a si misma cuando haya que procesar una subcarpeta. Así se llamará las veces que sea necesaria para llegar al final del árbol de subcarpetas. No tiene ningún misterio.

Saludos

Responder

Agregar comentario

Los datos anteriores se utilizarán exclusivamente para permitirte hacer el comentario y, si lo seleccionas, notificarte de nuevos comentarios en este artículo, pero no se procesarán ni se utilizarán para ningún otro propósito. Lee nuestra política de privacidad.