Trabalhando com o sistema de arquivos em Go: para iniciantes
Go (Golang) é uma linguagem compilada moderna, conhecida por sua simplicidade, desempenho e ferramentas integradas. Uma das tarefas essenciais de qualquer desenvolvedor backend é interagir com o sistema de arquivos: ler configurações, escrever logs, criar arquivos e diretórios temporários. Neste artigo, abordaremos as operações básicas com arquivos e pastas em Go, começando do zero. O material é voltado para iniciantes, portanto, cada etapa será acompanhada de exemplos de código claros.
Pacotes principais para trabalhar com arquivos
Na biblioteca padrão do Go, existem dois pacotes principais para trabalhar com o sistema de arquivos:
os— trabalho de baixo nível com arquivos, pastas, permissões de acesso e processos.io/ioutil(obsoleto no Go 1.16, mas ainda encontrado) — funções convenientes para ler/escrever arquivos inteiros.io— interfaces para entrada/saída de fluxo.bufio— leitura/escrita com buffer (útil para arquivos grandes).
A partir do Go 1.16, é recomendado usar funções do pacote os (os.ReadFile, os.WriteFile) em vez de ioutil. Vamos nos basear na abordagem moderna.
Leitura de arquivos
A maneira mais simples de ler um arquivo pequeno inteiro é usar os.ReadFile. Ele retorna uma fatia de bytes e um erro.
package main
import ( "fmt" "os")
func main() { // Leitura do arquivo inteiro data, err := os.ReadFile("example.txt") if err != nil { fmt.Println("Erro ao ler o arquivo:", err) return } fmt.Println("Conteúdo do arquivo:") fmt.Println(string(data))}Se o arquivo for grande (por exemplo, um arquivo de log com centenas de megabytes), é melhor lê-lo linha por linha ou em blocos usando bufio.Scanner:
package main
import ( "bufio" "fmt" "os")
func main() { file, err := os.Open("bigfile.log") if err != nil { fmt.Println("Erro ao abrir o arquivo:", err) return } defer file.Close() // fechamos o arquivo obrigatoriamente
scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() fmt.Println(line) // processamos a linha }
if err := scanner.Err(); err != nil { fmt.Println("Erro de escaneamento:", err) }}Observe o defer file.Close() — isso garante que o arquivo será fechado após a conclusão da função, mesmo que ocorra um erro.
Escrita em arquivos
Para escrever dados em um arquivo, use os.WriteFile (cria/sobrescreve o arquivo) ou os.Create + Write (para escrita mais flexível).
package main
import ( "fmt" "os")
func main() { // Escrita simples de uma string em um arquivo text := "Olá, mundo!Segunda linha." err := os.WriteFile("output.txt", []byte(text), 0644) if err != nil { fmt.Println("Erro ao escrever:", err) return } fmt.Println("Arquivo escrito com sucesso")}O parâmetro 0644 são as permissões de acesso no estilo Unix (o proprietário pode ler/escrever, os demais apenas leem).
Se precisar adicionar dados ao final do arquivo (append), use os.OpenFile com a flag os.O_APPEND:
package main
import ( "fmt" "os")
func main() { file, err := os.OpenFile("log.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Println("Erro ao abrir o arquivo:", err) return } defer file.Close()
_, err = file.WriteString("Nova entrada no log") if err != nil { fmt.Println("Erro ao escrever:", err) }}