---
title: "File e OpenOptions em Rust"
url: "https://rustlang.com.br/stdlib/file/"
markdown_url: "https://rustlang.com.br/stdlib/file.MD"
description: "Referência completa de File e OpenOptions em Rust: abrir, criar, ler, escrever, append, truncate, metadata, permissões e seek com exemplos."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# File e OpenOptions em Rust

Referência completa de File e OpenOptions em Rust: abrir, criar, ler, escrever, append, truncate, metadata, permissões e seek com exemplos.


# File e OpenOptions em Rust

O tipo `std::fs::File` representa um arquivo aberto no sistema operacional. Ele implementa as traits `Read`, `Write` e `Seek`, permitindo leitura, escrita e navegação posicional. Para controle fino sobre como um arquivo é aberto (leitura, escrita, append, truncamento, criação), use `std::fs::OpenOptions`, que fornece um builder configurável.

## Visão geral e tipos-chave

### File

`File` é um handle para um arquivo aberto. Quando o `File` sai de escopo, o arquivo é fechado automaticamente (via `Drop`). Os dois métodos estáticos mais usados são:

- **`File::open(path)`** — abre para leitura (equivale a `OpenOptions::new().read(true).open(path)`)
- **`File::create(path)`** — cria ou trunca para escrita (equivale a `OpenOptions::new().write(true).create(true).truncate(true).open(path)`)

### OpenOptions

`OpenOptions` é um builder que configura como o arquivo será aberto:

- **`read(true)`** — permite leitura
- **`write(true)`** — permite escrita
- **`append(true)`** — posiciona no final para escrita (implica `write`)
- **`truncate(true)`** — limpa o conteúdo ao abrir (requer `write`)
- **`create(true)`** — cria se não existir (requer `write` ou `append`)
- **`create_new(true)`** — falha se o arquivo já existir (garante criação exclusiva)

### Metadata e Permissions

- **`Metadata`** — informações sobre o arquivo: tamanho, tipo, timestamps, permissões.
- **`Permissions`** — permite verificar e alterar permissões de leitura/escrita.

## Padrões comuns com código

### Abrir e ler arquivo

```rust
use std::fs::File;
use std::io::{self, Read};

fn main() -> io::Result<()> {
    // Abrir para leitura
    let mut arquivo = File::open("config.toml")?;
    let mut conteudo = String::new();
    arquivo.read_to_string(&mut conteudo)?;
    println!("Configuração ({} bytes):\n{}", conteudo.len(), conteudo);
    Ok(())
}
```

### Criar e escrever arquivo

```rust
use std::fs::File;
use std::io::{self, Write};

fn main() -> io::Result<()> {
    // File::create trunca se existir, cria se não existir
    let mut arquivo = File::create("resultado.txt")?;
    writeln!(arquivo, "Relatório gerado em 2026-02-23")?;
    writeln!(arquivo, "Total de registros: {}", 42)?;
    arquivo.flush()?;
    Ok(())
}
```

### Adicionar conteúdo com append

```rust
use std::fs::OpenOptions;
use std::io::{self, Write};

fn adicionar_log(caminho: &str, mensagem: &str) -> io::Result<()> {
    let mut arquivo = OpenOptions::new()
        .append(true)
        .create(true)
        .open(caminho)?;

    writeln!(arquivo, "[{}] {}", chrono_simples(), mensagem)?;
    Ok(())
}

fn chrono_simples() -> String {
    // Simulação simples de timestamp
    "2026-02-23 14:30:00".to_string()
}

fn main() -> io::Result<()> {
    adicionar_log("app.log", "Servidor iniciado")?;
    adicionar_log("app.log", "Conexão recebida de 192.168.1.10")?;
    adicionar_log("app.log", "Processamento concluído")?;
    println!("Logs adicionados com sucesso");
    Ok(())
}
```

### Uso avançado de OpenOptions

```rust
use std::fs::OpenOptions;
use std::io::{self, Read, Write, Seek, SeekFrom};

fn main() -> io::Result<()> {
    // Abrir para leitura E escrita
    let mut arquivo = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .open("dados.bin")?;

    // Escrever dados iniciais
    arquivo.write_all(b"AAAAAAAAAA")?;

    // Voltar ao início
    arquivo.seek(SeekFrom::Start(0))?;

    // Ler o que foi escrito
    let mut conteudo = String::new();
    arquivo.read_to_string(&mut conteudo)?;
    println!("Conteúdo: {}", conteudo);

    // Sobrescrever parcialmente (posição 3)
    arquivo.seek(SeekFrom::Start(3))?;
    arquivo.write_all(b"BBB")?;

    // Ler tudo novamente
    arquivo.seek(SeekFrom::Start(0))?;
    conteudo.clear();
    arquivo.read_to_string(&mut conteudo)?;
    println!("Após edição: {}", conteudo); // AAABBBAAAA

    Ok(())
}
```

## Tabela de métodos e funções

### Métodos de File

| Método | Descrição |
|---|---|
| `File::open(path)` | Abre para leitura |
| `File::create(path)` | Cria/trunca para escrita |
| `File::create_new(path)` | Cria novo arquivo, falha se existir |
| `metadata()` | Retorna metadados (tamanho, permissões, etc.) |
| `set_permissions(perm)` | Altera permissões do arquivo |
| `set_len(size)` | Define o tamanho do arquivo (trunca ou estende) |
| `sync_all()` | Sincroniza dados e metadados com o disco |
| `sync_data()` | Sincroniza apenas dados com o disco |
| `try_clone()` | Cria handle duplicado para o mesmo arquivo |
| `set_modified(time)` | Define timestamp de modificação |

### Métodos de OpenOptions

| Método | Descrição |
|---|---|
| `OpenOptions::new()` | Cria builder com todas opções desativadas |
| `read(bool)` | Habilita leitura |
| `write(bool)` | Habilita escrita |
| `append(bool)` | Escrita no final (implica write) |
| `truncate(bool)` | Limpa conteúdo ao abrir |
| `create(bool)` | Cria se não existir |
| `create_new(bool)` | Falha se já existir |
| `open(path)` | Abre o arquivo com as opções configuradas |

### Métodos de Seek

| Método | Descrição |
|---|---|
| `seek(SeekFrom::Start(n))` | Posiciona em N bytes do início |
| `seek(SeekFrom::End(n))` | Posiciona em N bytes do final |
| `seek(SeekFrom::Current(n))` | Move N bytes da posição atual |
| `rewind()` | Volta ao início (equivale a `seek(Start(0))`) |
| `stream_position()` | Retorna a posição atual |

## Exemplos práticos

### Exemplo 1: Criação exclusiva de arquivo (evitar sobrescrita)

```rust
use std::fs::{File, OpenOptions};
use std::io::{self, Write};

fn criar_arquivo_seguro(caminho: &str, conteudo: &str) -> io::Result<()> {
    // create_new() falha se o arquivo já existir
    match File::create_new(caminho) {
        Ok(mut arquivo) => {
            arquivo.write_all(conteudo.as_bytes())?;
            println!("Arquivo '{}' criado com sucesso", caminho);
            Ok(())
        }
        Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {
            eprintln!("Arquivo '{}' já existe — não sobrescrevendo", caminho);
            Err(e)
        }
        Err(e) => Err(e),
    }
}

fn main() -> io::Result<()> {
    criar_arquivo_seguro("relatorio_2026.txt", "Dados do relatório...")?;
    Ok(())
}
```

### Exemplo 2: Arquivo de configuração com leitura/escrita

```rust
use std::fs::OpenOptions;
use std::io::{self, BufRead, BufReader, Seek, SeekFrom, Write};

fn atualizar_config(caminho: &str, chave: &str, novo_valor: &str) -> io::Result<bool> {
    let mut arquivo = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .open(caminho)?;

    let leitor = BufReader::new(&arquivo);
    let mut linhas: Vec<String> = Vec::new();
    let mut encontrou = false;

    for resultado in leitor.lines() {
        let linha = resultado?;
        if linha.starts_with(&format!("{}=", chave)) || linha.starts_with(&format!("{} =", chave)) {
            linhas.push(format!("{} = {}", chave, novo_valor));
            encontrou = true;
        } else {
            linhas.push(linha);
        }
    }

    if !encontrou {
        linhas.push(format!("{} = {}", chave, novo_valor));
    }

    // Reescrever o arquivo
    arquivo.seek(SeekFrom::Start(0))?;
    arquivo.set_len(0)?; // truncar
    for linha in &linhas {
        writeln!(arquivo, "{}", linha)?;
    }

    arquivo.sync_all()?;
    Ok(encontrou)
}

fn main() -> io::Result<()> {
    let atualizado = atualizar_config("app.conf", "porta", "8080")?;
    if atualizado {
        println!("Configuração atualizada");
    } else {
        println!("Nova configuração adicionada");
    }
    Ok(())
}
```

### Exemplo 3: Consultar metadados e permissões

```rust
use std::fs;
use std::io;

fn exibir_info_arquivo(caminho: &str) -> io::Result<()> {
    let metadata = fs::metadata(caminho)?;

    println!("Arquivo: {}", caminho);
    println!("  Tamanho: {} bytes", metadata.len());
    println!("  É arquivo: {}", metadata.is_file());
    println!("  É diretório: {}", metadata.is_dir());
    println!("  É symlink: {}", metadata.is_symlink());
    println!("  Somente leitura: {}", metadata.permissions().readonly());

    if let Ok(modificado) = metadata.modified() {
        println!("  Modificado: {:?}", modificado);
    }

    if let Ok(criado) = metadata.created() {
        println!("  Criado: {:?}", criado);
    }

    Ok(())
}

fn tornar_somente_leitura(caminho: &str) -> io::Result<()> {
    let metadata = fs::metadata(caminho)?;
    let mut permissoes = metadata.permissions();
    permissoes.set_readonly(true);
    fs::set_permissions(caminho, permissoes)?;
    println!("'{}' agora é somente leitura", caminho);
    Ok(())
}

fn main() -> io::Result<()> {
    exibir_info_arquivo("Cargo.toml")?;
    Ok(())
}
```

### Exemplo 4: Seek para edição em arquivos binários

```rust
use std::fs::OpenOptions;
use std::io::{self, Read, Seek, SeekFrom, Write};

/// Lê e modifica um campo em posição fixa de um arquivo binário
fn editar_campo_binario(
    caminho: &str,
    offset: u64,
    novo_valor: &[u8],
) -> io::Result<Vec<u8>> {
    let mut arquivo = OpenOptions::new()
        .read(true)
        .write(true)
        .open(caminho)?;

    // Ler valor antigo
    arquivo.seek(SeekFrom::Start(offset))?;
    let mut valor_antigo = vec![0u8; novo_valor.len()];
    arquivo.read_exact(&mut valor_antigo)?;

    // Escrever novo valor
    arquivo.seek(SeekFrom::Start(offset))?;
    arquivo.write_all(novo_valor)?;
    arquivo.sync_data()?;

    println!(
        "Offset {}: {:02X?} -> {:02X?}",
        offset, valor_antigo, novo_valor
    );

    Ok(valor_antigo)
}

fn main() -> io::Result<()> {
    // Criar arquivo de exemplo
    let mut f = std::fs::File::create("teste.bin")?;
    f.write_all(&[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07])?;
    drop(f);

    // Editar bytes na posição 2
    let antigo = editar_campo_binario("teste.bin", 2, &[0xFF, 0xFE])?;
    println!("Valor anterior: {:02X?}", antigo);

    Ok(())
}
```

### Exemplo 5: sync_all para garantia de persistência

```rust
use std::fs::File;
use std::io::{self, Write};

/// Escrita durável — garante que dados estejam no disco físico
fn escrever_duravel(caminho: &str, dados: &[u8]) -> io::Result<()> {
    let mut arquivo = File::create(caminho)?;
    arquivo.write_all(dados)?;

    // sync_all() garante que dados E metadados estejam no disco
    // Importante para bancos de dados, logs de transação, etc.
    arquivo.sync_all()?;

    Ok(())
}

/// Escrita atômica via arquivo temporário + rename
fn escrever_atomico(caminho: &str, dados: &[u8]) -> io::Result<()> {
    let caminho_temp = format!("{}.tmp", caminho);

    // 1. Escrever no arquivo temporário
    let mut temp = File::create(&caminho_temp)?;
    temp.write_all(dados)?;
    temp.sync_all()?;
    drop(temp);

    // 2. Renomear atomicamente (no mesmo filesystem)
    std::fs::rename(&caminho_temp, caminho)?;

    Ok(())
}

fn main() -> io::Result<()> {
    escrever_duravel("dados_importantes.dat", b"dados criticos")?;
    escrever_atomico("config.json", b"{\"chave\": \"valor\"}")?;
    println!("Escritas duráveis concluídas");
    Ok(())
}
```

## Padrões de tratamento de erro para I/O

### Erros comuns ao trabalhar com arquivos

```rust
use std::fs::File;
use std::io;

fn abrir_com_diagnostico(caminho: &str) -> io::Result<File> {
    File::open(caminho).map_err(|e| {
        match e.kind() {
            io::ErrorKind::NotFound => {
                eprintln!("Arquivo não encontrado: '{}'", caminho);
                eprintln!("Verifique o caminho e tente novamente.");
            }
            io::ErrorKind::PermissionDenied => {
                eprintln!("Sem permissão para abrir: '{}'", caminho);
                eprintln!("Verifique as permissões do arquivo.");
            }
            _ => {
                eprintln!("Erro inesperado ao abrir '{}': {}", caminho, e);
            }
        }
        e
    })
}
```

### Padrão try_clone para leitura e escrita simultâneas

```rust
use std::fs::OpenOptions;
use std::io::{self, BufRead, BufReader, Write, Seek, SeekFrom};

fn ler_e_registrar(caminho_dados: &str, caminho_log: &str) -> io::Result<()> {
    let arquivo = OpenOptions::new().read(true).open(caminho_dados)?;

    // Clonar handle para usar em dois contextos
    let clone = arquivo.try_clone()?;
    let leitor = BufReader::new(arquivo);
    let mut log = std::fs::File::create(caminho_log)?;

    for (i, linha) in leitor.lines().enumerate() {
        let linha = linha?;
        writeln!(log, "Linha {}: {} chars", i + 1, linha.len())?;
    }

    Ok(())
}
```

## Dicas de desempenho

- **Use `BufReader` e `BufWriter`** ao fazer múltiplas operações pequenas sobre um `File`. A diferença pode ser de 10x a 100x em performance.
- **Use `sync_data()` em vez de `sync_all()`** quando não precisar sincronizar metadados — é mais rápido em alguns sistemas de arquivos.
- **Pré-aloque com `set_len()`** quando souber o tamanho final do arquivo para evitar fragmentação.
- **Escrita atômica via rename** é mais segura que sobrescrever diretamente — evita corrupção em caso de falha de energia.

## Veja também

- [Módulo std::io](/stdlib/io-module/) — visão geral do sistema de I/O
- [Read e Write Traits](/stdlib/read-write/) — traits implementadas por File
- [BufReader e BufWriter](/stdlib/bufreader-bufwriter/) — buffering para performance
- [Módulo std::fs](/stdlib/fs-module/) — operações de filesystem de alto nível
- [Path e PathBuf](/stdlib/path/) — manipulação de caminhos
- [Ler Arquivo em Rust](/receitas/ler-arquivo/) — receita prática de leitura
- [Escrever em Arquivo](/receitas/escrever-arquivo/) — receita prática de escrita
- Documentação oficial: [`std::fs::File`](https://doc.rust-lang.org/std/fs/struct.File.html), [`std::fs::OpenOptions`](https://doc.rust-lang.org/std/fs/struct.OpenOptions.html)
