FileUtils, de Apache Commons IO, resume en una línea tareas con archivos que con java.io llevaban diez. Este es el ejemplo de siempre, leer un archivo y listar los de ciertas extensiones, puesto al día. Y al lado, la versión con java.nio, que hoy hace casi lo mismo sin añadir nada.
También te puede interesar
La dependencia
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.22.0</version>
</dependency>Es la última versión publicada en Maven Central. Si no usas Maven, basta con descargar el .jar y añadirlo al classpath.
El ejemplo
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
public class Prueba {
public static void main(String[] args) throws IOException {
File archivo = new File("ejemplo.txt");
String contenido = FileUtils.readFileToString(archivo, StandardCharsets.UTF_8);
System.out.println("contenido: " + contenido.strip());
String[] extensiones = {"xml", "java", "dat"};
Collection<File> archivos = FileUtils.listFiles(new File("proy"), extensiones, true);
for (File f : archivos) {
System.out.println("> " + f.getPath());
}
}
}Lo probamos con un ejemplo.txt de una línea y una carpeta proy con seis archivos, de los que solo tres tienen las extensiones que buscamos:
javac -cp commons-io-2.22.0.jar Prueba.java java -cp .:commons-io-2.22.0.jar Prueba
salidacontenido: Hola desde decodigo.com > proy/pom.xml > proy/src/main/java/ejemplo/App.java > proy/datos/clientes.dat
Encontró el .xml, el .java y el .dat, en cualquier nivel de subcarpetas, y dejó fuera el .txt, el .md y el .class. El orden es el que devuelve el sistema de archivos, que no tiene por qué ser alfabético.
Lo que cambió desde la versión de 2011
El código original llamaba a readFileToString(archivo) sin indicar la codificación. Ese método está obsoleto:
javac -Xlint:deprecationVieja.java:6: warning: [deprecation] readFileToString(File) in FileUtils has been deprecated
System.out.println(FileUtils.readFileToString(new File("ejemplo.txt")).strip());
^
1 warningSin codificación, el archivo se lee con la del sistema, y el mismo programa puede leer bien los acentos en un equipo y mal en otro. Por eso hay que pasar siempre StandardCharsets.UTF_8 (o la que tenga el archivo). El otro cambio es de estilo: la lista ahora es una Collection<File> con tipo, y se recorre con un for normal, sin Iterator ni conversiones.
Lo mismo sin dependencias
import java.io.IOException;
import java.nio.file.*;
import java.util.Set;
import java.util.stream.Stream;
void main() throws IOException {
String contenido = Files.readString(Path.of("ejemplo.txt"));
IO.println("contenido: " + contenido.strip());
Set<String> extensiones = Set.of("xml", "java", "dat");
try (Stream<Path> rutas = Files.walk(Path.of("proy"))) {
rutas.filter(Files::isRegularFile)
.filter(p -> {
String n = p.getFileName().toString();
int punto = n.lastIndexOf('.');
return punto > 0 && extensiones.contains(n.substring(punto + 1));
})
.sorted()
.forEach(p -> IO.println("> " + p));
}
}java SinDependencias.javacontenido: Hola desde decodigo.com > proy/datos/clientes.dat > proy/pom.xml > proy/src/main/java/ejemplo/App.java
Files.readString lee en UTF-8 por omisión, y Files.walk recorre el árbol. Filtrar por extensión lleva unas líneas más que con FileUtils, pero no hace falta ningún .jar. Aquí además las ordenamos con sorted(). El try con recursos es necesario, porque Files.walk deja abiertos los directorios hasta que se cierra el stream.
| Para… | Commons IO | java.nio (JDK) |
|---|---|---|
| Leer un archivo entero | FileUtils.readFileToString(f, UTF_8) | Files.readString(ruta) |
| Escribir un archivo | FileUtils.writeStringToFile(f, texto, UTF_8) | Files.writeString(ruta, texto) |
| Listar por extensión, recursivo | FileUtils.listFiles(dir, exts, true) | Files.walk + filtro |
| Copiar un directorio entero | FileUtils.copyDirectory(a, b) | a mano, con Files.walk |
| Borrar un directorio con contenido | FileUtils.deleteDirectory(dir) | a mano, con Files.walk al revés |
Para leer y escribir, java.nio basta. Commons IO sigue ahorrando trabajo en las operaciones con directorios enteros, como copiarlos o borrarlos. Las vemos, con sus salidas, en FileUtils de Commons IO.
Entrada publicada en 2011 y revisada en octubre de 2026. Todo el código se compiló y se ejecutó con Java 25 LTS en un contenedor limpio con Commons IO 2.22.0; las salidas están copiadas de esa ejecución.