Como listar arquivos em um diretório no Rust: tutorial passo a passo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: por que você pode precisar de uma lista de arquivos no Rust?

\n\n

Imagine: você está escrevendo no Rust um utilitário para backup, um analisador de logs ou um simples gerenciador de arquivos. E surge uma tarefa básica, mas crítica — obter a lista de todos os arquivos em um diretório especificado. Parece simples, não? Mas no Rust, com sua tipagem forte e sistema de ownership, até mesmo uma operação tão simples esconde algumas armadilhas.

\n\n

A pergunta «How can I list files of a directory in Rust?» é uma das mais populares no Stack Overflow (milhares de visualizações!). E não é por acaso: iniciantes frequentemente tropeçam no std::fs::read_dir, se confundem com iteradores e esquecem do tratamento de erros. Neste tutorial, mostrarei duas abordagens funcionais: a simples (apenas arquivos em uma pasta) e a avançada (travessia recursiva de todos os subdiretórios). Vamos lá!

\n\n

1. Preparação: criando um novo projeto

\n\n

Antes de escrever código, vamos criar um novo projeto binário. Abra o terminal e execute:

\n\n
cargo new list_files_rs\ncd list_files_rs
\n\n

Agora abra src/main.rs — é aqui que escreveremos todo o código. Para começar, não precisaremos de dependências externas, apenas da biblioteca padrão do Rust — std.

\n\n

2. A maneira mais simples: std::fs::read_dir

\n\n

A função std::fs::read_dir retorna um iterador sobre as entradas do diretório. Cada entrada é um DirEntry, que contém nome, caminho, tipo e metadados do arquivo. Vamos escrever um exemplo básico:

\n\n
use std::fs;\nuse std::path::Path;\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let path = Path::new("."); // diretório atual\n\n    // Lê o conteúdo da pasta\n    let entries = fs::read_dir(path)?;\n\n    for entry in entries {\n        let entry = entry?; // desempacota o Result\n        let path = entry.path();\n\n        // Verifica se é um arquivo (não um diretório)\n        if path.is_file() {\n            println!("{}", path.display());\n        }\n    }\n\n    Ok(())\n}
\n\n

O que está acontecendo aqui?

\n
    \n
  • fs::read_dir(path) — abre o diretório e retorna um ReadDir (iterador).
  • \n
  • Percorremos cada entrada. Cada chamada a next() retorna um Result<DirEntry> — por isso precisamos do entry?.
  • \n
  • entry.path() retorna o caminho completo para o arquivo/pasta.
  • \n
  • O método path.is_file() filtra os subdiretórios.
  • \n
\n\n

Execute o código com o comando cargo run — você verá a lista de arquivos na raiz do projeto (por exemplo, Cargo.toml, src/main.rs).

\n\n

2.1. Filtragem por extensão

\n\n

Frequentemente, precisamos obter apenas arquivos específicos, como apenas .rs ou .txt. Vamos adicionar um filtro:

\n\n
use std::fs;\nuse std::path::Path;\n\nfn main() -> Result<(), Box<dyn std::error::Error>> {\n    let path = Path::new(".");\n\n    for entry in fs::read_dir(path)? {\n        let entry = entry?;\n        let path = entry.path();\n\n        // Verifica se é um arquivo e a extensão é .rs\n        if path.is_file() && path.extension().map_or(false, |ext| ext == "rs") {\n            println!("{}", path.display());\n        }\n    }\n\n    Ok(())\n}
\n\n

O truque com map_or é necessário para tratar com segurança o caso em que o arquivo não tem extensão — path.extension() retorna Option<&OsStr>.

\n\n

3. Travessia recursiva: explorando todas as subpastas

\n\n

O simples read_dir não entra em subdiretórios. Se você precisar coletar todos os arquivos recursivamente (por exemplo, para buscar duplicatas), terá que escrever sua própria função recursiva. Aqui está uma solução elegante:

\n\n
use std::fs;\nuse std::path::Path;\n\nfn visit_dirs(dir: &Path, depth: usize) -> Result<(), Box&l                

Blogs

Book Recommendations