Crear carpetas anidadas y recorrer su contenido son dos llamadas de std::fs. Lo interesante es el recorrido, porque encaja con los iteradores de Rust y permite filtrar por extensión en una sola expresión.
También te puede interesar
Crear, listar y limpiar
use std::fs;
fn main() -> std::io::Result<()> {
fs::create_dir_all("datos/informes/2026")?;
println!("carpetas creadas");
fs::write("datos/notas.txt", "x")?;
fs::write("datos/informe.csv", "y")?;
fs::write("datos/resumen.txt", "z")?;
let mut textos: Vec<String> = fs::read_dir("datos")?
.filter_map(|e| e.ok())
.map(|e| e.path())
.filter(|p| p.extension().is_some_and(|x| x == "txt"))
.filter_map(|p| p.file_name().map(|n| n.to_string_lossy().into_owned()))
.collect();
textos.sort();
println!("archivos .txt: {textos:?}");
fs::remove_dir_all("datos")?;
println!("carpeta eliminada con todo su contenido");
Ok(())
}
salidacarpetas creadas archivos .txt: ["notas.txt", "resumen.txt"] carpeta eliminada con todo su contenido
create_dir_all crea toda la jerarquía que falte, como mkdir -p, y no se queja si ya existía. Su hermana create_dir solo crea un nivel y falla si el padre no está, que casi nunca es lo que se quiere.
El recorrido, paso a paso
La cadena de iteradores del ejemplo hace cinco cosas, y conviene leerla de arriba abajo como una frase. read_dir entrega cada entrada envuelta en un Result, porque leer una concreta puede fallar; filter_map(|e| e.ok()) descarta las que fallaron y desempaqueta el resto. Luego se pasa a la ruta, se filtra por extensión y se extrae el nombre del archivo.
El sort() del final no es decorativo: el orden en que el sistema de archivos devuelve las entradas no está garantizado. Sin ordenar, el mismo programa puede dar las dos líneas en distinto orden en otra máquina. Es el mismo cuidado que hay que tener con los HashMap de la lección de colecciones.
to_string_lossy y no to_str. Los nombres de archivo no son necesariamente texto UTF-8 válido: el sistema operativo admite secuencias de bytes que no lo son. Rust lo refleja usando OsString en vez de String. to_string_lossy convierte sustituyendo lo no válido, que para mostrar por pantalla está bien; to_str devolvería None y habría que decidir qué hacer.Lo que se usa a diario
| Qué quieres | Llamada |
|---|---|
| Crear una carpeta y sus padres | fs::create_dir_all(ruta) |
| Listar el contenido | fs::read_dir(ruta) |
| Saber si una entrada es carpeta | e.file_type()?.is_dir() |
| La extensión | ruta.extension() |
| El nombre sin la carpeta | ruta.file_name() |
| Recorrer también las subcarpetas | el crate walkdir |
Buscar por patrón tipo *.txt |
el crate glob |
La biblioteca estándar no recorre subcarpetas por su cuenta: read_dir ve un solo nivel. Para bajar por todo el árbol, o se escribe una función recursiva o se usa walkdir, que es lo habitual.
El código de esta página se compiló y ejecutó con rustc 1.96.1 antes de publicarla; las salidas están copiadas de la ejecución real. Documentación oficial: el módulo std::fs.