Ler Arquivo em Rust
Ler arquivos é uma operação essencial em qualquer programa. Rust fornece APIs seguras e eficientes para leitura de arquivos, desde métodos simples para arquivos pequenos até leitura bufferizada para arquivos grandes.
Ler arquivo inteiro com fs::read_to_string()
A forma mais simples de ler um arquivo inteiro para uma String:
use std::fs;
fn main() {
// Forma mais simples — arquivo inteiro em uma String
match fs::read_to_string("exemplo.txt") {
Ok(conteudo) => {
println!("Conteúdo ({} bytes):", conteudo.len());
println!("{}", conteudo);
}
Err(e) => eprintln!("Erro ao ler arquivo: {}", e),
}
}
Saída (com arquivo exemplo.txt contendo “Olá Rust!\nSegunda linha”):
Conteúdo (27 bytes):
Olá Rust!
Segunda linha
Ler arquivo com tratamento robusto de erros
Em código de produção, use o operador ? com funções que retornam Result:
use std::fs;
use std::io;
use std::path::Path;
fn ler_arquivo_seguro(caminho: &str) -> Result<String, io::Error> {
let path = Path::new(caminho);
// Verificar se o arquivo existe
if !path.exists() {
return Err(io::Error::new(
io::ErrorKind::NotFound,
format!("Arquivo não encontrado: {}", caminho),
));
}
// Verificar se é um arquivo (não diretório)
if !path.is_file() {
return Err(io::Error::new(
io::ErrorKind::InvalidInput,
format!("Não é um arquivo: {}", caminho),
));
}
fs::read_to_string(caminho)
}
fn main() {
match ler_arquivo_seguro("config.toml") {
Ok(conteudo) => println!("Config:\n{}", conteudo),
Err(e) => eprintln!("Erro: {}", e),
}
// Múltiplos arquivos com tratamento individual
let arquivos = vec!["dados.txt", "config.toml", "notas.md"];
for arquivo in arquivos {
match fs::read_to_string(arquivo) {
Ok(c) => println!("✓ {} ({} bytes)", arquivo, c.len()),
Err(e) => println!("✗ {}: {}", arquivo, e),
}
}
}
Ler arquivo linha por linha com BufReader
Para arquivos grandes, use BufReader para ler linha por linha sem carregar tudo na memória:
use std::fs::File;
use std::io::{self, BufRead, BufReader};
fn main() -> io::Result<()> {
let arquivo = File::open("dados.txt")?;
let leitor = BufReader::new(arquivo);
// Ler linha por linha
for (numero, linha) in leitor.lines().enumerate() {
let linha = linha?; // lines() retorna Result por linha
println!("{:4}: {}", numero + 1, linha);
}
Ok(())
}
Saída (com arquivo de exemplo):
1: Primeira linha do arquivo
2: Segunda linha com dados
3: Terceira linha final
Exemplo prático: processar arquivo de log
Um exemplo mais completo que lê um arquivo de log, filtra por nível e conta ocorrências:
use std::collections::HashMap;
use std::fs::File;
use std::io::{self, BufRead, BufReader};
fn processar_log(caminho: &str) -> io::Result<()> {
let arquivo = File::open(caminho)?;
let leitor = BufReader::new(arquivo);
let mut contagem: HashMap<String, usize> = HashMap::new();
let mut total = 0;
for linha in leitor.lines() {
let linha = linha?;
total += 1;
// Extrair nível de log (ex: "2026-02-23 ERROR mensagem")
if let Some(nivel) = linha.split_whitespace().nth(1) {
*contagem.entry(nivel.to_string()).or_insert(0) += 1;
}
}
println!("Total de linhas: {}", total);
println!("Contagem por nível:");
for (nivel, quantidade) in &contagem {
println!(" {}: {}", nivel, quantidade);
}
Ok(())
}
fn main() {
if let Err(e) = processar_log("servidor.log") {
eprintln!("Erro ao processar log: {}", e);
}
}
Ler arquivo binário (bytes)
Para arquivos que não são texto puro, leia como bytes:
use std::fs;
use std::io::{self, Read};
fn main() -> io::Result<()> {
// Ler tudo como Vec<u8>
let bytes = fs::read("imagem.png")?;
println!("Tamanho: {} bytes", bytes.len());
println!("Primeiros 16 bytes: {:?}", &bytes[..16.min(bytes.len())]);
// Ler chunks com BufReader
let mut arquivo = fs::File::open("dados.bin")?;
let mut buffer = [0u8; 1024]; // buffer de 1KB
loop {
let n = arquivo.read(&mut buffer)?;
if n == 0 {
break; // fim do arquivo
}
println!("Lidos {} bytes", n);
}
Ok(())
}
Ler com codificação específica
Quando o arquivo não está em UTF-8, use a crate encoding_rs:
Cargo.toml:
[dependencies]
encoding_rs = "0.8"
use std::fs;
fn main() {
let bytes = fs::read("arquivo_latin1.txt").expect("Erro ao ler");
// Decodificar de ISO-8859-1 (Latin-1)
let (texto, _, tinha_erros) = encoding_rs::WINDOWS_1252.decode(&bytes);
if tinha_erros {
eprintln!("Aviso: alguns caracteres não puderam ser decodificados");
}
println!("Conteúdo: {}", texto);
}
Resumo dos métodos
| Método | Quando usar |
|---|---|
fs::read_to_string() | Arquivos pequenos de texto |
BufReader::lines() | Arquivos grandes, leitura linha por linha |
fs::read() | Arquivos binários |
BufReader + read() | Arquivos muito grandes, leitura em chunks |
Veja também
- Escrever em Arquivo — a operação complementar de escrita
- Ler Arquivo CSV — parse específico para formato CSV
- Dividir String — processe o conteúdo lido do arquivo
- Converter String para Número — converta dados lidos para números
- Parse JSON em Rust — leia e parse arquivos JSON
- Documentação oficial:
std::fs