Trabalhando com o sistema de arquivos em Go: um guia prático
Go (Golang) é uma linguagem compilada moderna, ideal para criar aplicações de servidor, utilitários e ferramentas de linha de comando. Uma das tarefas principais nesses projetos é trabalhar com o sistema de arquivos. Neste artigo, abordaremos exemplos práticos: desde abrir e ler arquivos até percorrer diretórios recursivamente. Todos os exemplos são escritos em Go puro, sem bibliotecas de terceiros.
Fundamentos: abrir, ler e escrever arquivos
O pacote os fornece funções para trabalho de baixo nível com arquivos. Para ler todo o conteúdo de um arquivo na memória, use os.ReadFile (disponível desde o Go 1.16).
package main
import ( "fmt" "os")
func main() { data, err := os.ReadFile("example.txt") if err != nil { fmt.Println("Erro ao ler o arquivo:", err) return } fmt.Println(string(data))}Para escrever dados em um arquivo, existe a função os.WriteFile. Ela cria o arquivo se não existir ou sobrescreve o existente.
package main
import ( "fmt" "os")
func main() { content := []byte("Hello, Go!Segunda linha") err := os.WriteFile("output.txt", content, 0644) if err != nil { fmt.Println("Erro ao escrever:", err) return } fmt.Println("Arquivo escrito com sucesso")}O terceiro argumento 0644 são as permissões no estilo Unix (o proprietário pode ler e escrever, os demais apenas leitura). No Windows, este parâmetro é parcialmente ignorado.
Leitura e escrita em fluxo: trabalhando com arquivos grandes
Para trabalhar com arquivos grandes (mais de alguns megabytes), não carregue-os inteiramente na memória. Use leitura bufferizada com bufio ou o pacote io.
package main
import ( "bufio" "fmt" "os")
func main() { file, err := os.Open("large_file.log") if err != nil { fmt.Println("Erro ao abrir:", err) return } defer file.Close()
scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() // Processa a linha fmt.Println(line) }
if err := scanner.Err(); err != nil { fmt.Println("Erro de escaneamento:", err) }}Para escrita em fluxo, use bufio.NewWriter:
package main
import ( "bufio" "fmt" "os")
func main() { file, err := os.Create("output_stream.txt") if err != nil { fmt.Println("Erro ao criar:", err) return } defer file.Close()
writer := bufio.NewWriter(file) for i := 0; i < 10; i++ { _, err := writer.WriteString(fmt.Sprintf("Linha %d", i+1)) if err != nil { fmt.Println("Erro ao escrever:", err) return } } writer.Flush() // Importante: libera o buffer fmt.Println("Escrita concluída")}O método Flush() é obrigatório — sem ele, os dados podem permanecer no buffer e não serem gravados no arquivo.
Trabalhando com diretórios: criar, excluir e percorrer
Para criar um novo diretório, use os.Mkdir (uma pasta) ou os.MkdirAll (recursivamente, como mkdir -p).
package main
import ( "fmt" "os")
func main() { // Criar uma pasta err := os.Mkdir("new_folder", 0755) if err != nil { fmt.Println("Erro ao criar pasta:", err) }
// Criar estrutura aninhada err = os.MkdirAll("a/b/c/d", 0755) if err != nil { fmt.Println("Erro ao criar pastas aninhadas:", err) } else { fmt.Println("Pastas criadas") }}A exclusão de diretório é feita com os.Remove (apenas p