Go e arquivos: da abertura ao processamento de dados em fluxo

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

Por que trabalhar com arquivos em Go não é assustador, mas sim interessante?

\n\n

Quando abri a documentação do pacote os em Go pela primeira vez, pensei que me esperava uma lista tediosa de chamadas de sistema. Mas, investigando mais a fundo, percebi: trabalhar com arquivos e o sistema de arquivos em Go não é apenas ler bytes. É uma ferramenta poderosa que lhe dá controle total sobre os dados, sejam eles arquivos de configuração, logs, binários ou bancos de dados inteiros em CSV.

\n\n

Go foi criado para programação de sistemas, então seus autores (Ken Thompson, Rob Pike e outros) incorporaram o trabalho com arquivos diretamente no núcleo da linguagem. Sem dependências externas, apenas a biblioteca padrão, que funciona de forma rápida e previsível. Neste artigo, abordaremos todos os cenários: desde a simples leitura de um arquivo até a travessia recursiva de diretórios e o processamento em fluxo de grandes dados.

\n\n

Se você programa em Go e quer trabalhar com o sistema de arquivos com confiança, está no lugar certo. Vamos lá!

\n\n

Fundamentos: abrindo, lendo, fechando

\n\n

O primeiro passo é abrir o arquivo. Em Go, a função os.Open() é responsável por isso. Ela retorna um ponteiro para o arquivo e um erro. Erros em Go não são exceções, mas valores. Você deve sempre verificá-los.

\n\n
package main\n\nimport (\n    "fmt"\n    "os"\n)\n\nfunc main() {\n    file, err := os.Open("example.txt")\n    if err != nil {\n        fmt.Println("Erro ao abrir arquivo:", err)\n        return\n    }\n    defer file.Close() // obrigatório fechar o arquivo\n\n    // Lê o conteúdo\n    buf := make([]byte, 1024)\n    n, err := file.Read(buf)\n    if err != nil {\n        fmt.Println("Erro ao ler:", err)\n        return\n    }\n    fmt.Printf("Lidos %d bytes: %s\\n", n, string(buf[:n]))\n}\n
\n\n

Observe o defer file.Close(). Esta é uma expressão idiomática do Go: a chamada adiada garante que o arquivo será fechado mesmo em caso de pânico ou retorno antecipado. Esquecer de fechar o arquivo é uma má prática que leva ao vazamento de descritores.

\n\n

Lendo um arquivo inteiro em uma linha

\n\n

Se o arquivo for pequeno (até alguns megabytes), você pode usar os.ReadFile() (substituiu o obsoleto ioutil.ReadFile). Isso é conveniente para configurações ou dados de texto.

\n\n
data, err := os.ReadFile("config.yaml")\nif err != nil {\n    log.Fatal(err)\n}\nfmt.Println(string(data))\n
\n\n

A função abre, lê e fecha o arquivo automaticamente. Mas lembre-se: para arquivos grandes, essa abordagem é perigosa — você carregará o arquivo inteiro na memória.

\n\n

Escrevendo em arquivos: criando e anexando

\n\n

Para escrever, use os.Create() (cria um novo arquivo ou trunca um existente) e os.OpenFile() para configurações mais refinadas (por exemplo, anexar ao final).

\n\n
// Criando arquivo\nfile, err := os.Create("output.txt")\nif err != nil {\n    panic(err)\n}\ndefer file.Close()\n\n// Escrevendo string\n_, err = file.WriteString("Olá, arquivos Go!\\n")\nif err != nil {\n    panic(err)\n}\n\n// Escrevendo bytes\nbytes := []byte("Escrevendo slice de bytes\\n")\n_, err = file.Write(bytes)\nif err != nil {\n    panic(err)\n}\n
\n\n

Para anexar dados ao final de um arquivo existente, use flags:

\n\n
file, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\nif err != nil {\n    log.Fatal(err)\n}\ndefer file.Close()\n\nfile.WriteString("Nova entrada no log\\n")\n
\n\n

A flag os.O_APPEND garante que os dados sejam anexados ao final, em vez de sobrescrever o início.

\n\n

Trabalhando com diretórios: criando, excluindo, percorrendo

\n\n

O sistema de arquivos não são apenas arquivos, mas também pastas. Go fornece funções convenientes para trabalhar com diretórios.

\n\n

Criando e excluindo pastas

\n\n
// Criar uma pasta\nerr := os.Mkdir("newdir", 0755)\nif err != nil {\n    log.Fatal(err)\n}\n\n// Criar pastas aninhadas (como mkdir -p)\nerr = os.MkdirAll("path/to/nested/dir", 0755)\nif err != nil {\n    log.Fatal(err)\                

Blogs

Book Recommendations