Listagem de diretórios em Go: do simples ao complexo
\n\nTrabalhar com o sistema de arquivos é uma das tarefas básicas de qualquer linguagem de programação. Em Go, isso é implementado de forma tão elegante que até mesmo uma operação rotineira como list directory in Go se transforma em uma aventura fascinante. Se você já se perguntou: "Como faço para obter uma lista de arquivos em uma pasta em Go?" — você veio ao lugar certo. Hoje vamos analisar todas as formas possíveis, desde a saída simples até a travessia recursiva com filtragem.
\n\nPor que este tópico é tão popular no Stack Overflow? Porque Go oferece várias abordagens, e escolher a correta é metade do sucesso. Vamos ver o clássico os.ReadDir, o obsoleto ioutil.ReadDir (mas ainda pode ser encontrado em projetos antigos), e o poderoso filepath.Walk para travessia recursiva. Vamos lá!
1. Listagem mais simples: os.ReadDir
\n\nA partir do Go 1.16, o pacote os ganhou um novo método ReadDir, que se tornou o padrão de facto. Ele retorna uma fatia de objetos os.DirEntry — descrições leves de arquivos e pastas. Veja como funciona:
package main\n\nimport (\n "fmt"\n "os"\n "log"\n)\n\nfunc main() {\n // Lê o conteúdo do diretório atual\n entries, err := os.ReadDir(".")\n if err != nil {\n log.Fatal(err)\n }\n\n fmt.Println("Conteúdo da pasta atual:")\n for _, entry := range entries {\n fmt.Printf("- %s (diretório: %v)\\n", entry.Name(), entry.IsDir())\n }\n}\n\n\nEste código exibirá todos os arquivos e pastas no diretório atual. Observe: os.ReadDir não lê subpastas — apenas o primeiro nível. Se você precisa de list directory in Go recursivamente, continue lendo.
2. ioutil.ReadDir: antigo, mas familiar
\n\nAntes da versão Go 1.16, todos usavam ioutil.ReadDir. Ele retorna []os.FileInfo — uma estrutura mais pesada com informações completas do arquivo (tamanho, permissões, data de modificação). Embora o método esteja marcado como deprecated, você ainda pode encontrá-lo em código legado:
package main\n\nimport (\n "fmt"\n "io/ioutil"\n "log"\n)\n\nfunc main() {\n files, err := ioutil.ReadDir("./mydir")\n if err != nil {\n log.Fatal(err)\n }\n\n fmt.Println("Arquivos em mydir (método antigo):")\n for _, file := range files {\n fmt.Printf("Nome: %s, Tamanho: %d bytes\\n", file.Name(), file.Size())\n }\n}\n\n\nA principal diferença: ioutil.ReadDir ordena o resultado pelo nome do arquivo (como ls), enquanto os.ReadDir não. Se a ordem for importante, use sort.Slice ou ordenação manual.
3. Travessia recursiva com filepath.Walk
\n\nQuando você precisa percorrer todas as subpastas, filepath.Walk vem ao resgate. Esta função percorre a árvore de diretórios, chamando um callback para cada item encontrado. Ideal para backups, busca de arquivos ou análise de estrutura de projetos:
package main\n\nimport (\n "fmt"\n "os"\n "path/filepath"\n)\n\nfunc main() {\n root := "./myproject"\n err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {\n if err != nil {\n return err\n }\n fmt.Printf("Encontrado: %s (tamanho: %d)\\n", path, info.Size())\n return nil\n })\n if err != nil {\n fmt.Println("Erro na travessia:", err)\n }\n}\n\n\nUma nuance importante: filepath.Walk segue links simbólicos e pode entrar em um loop infinito se houver referências cíclicas. Para produção, use filepath.WalkDir (Go 1.16+) — é mais leve e seguro.
4. Filtragem: apenas arquivos .go ou apenas pastas
\n\nMuitas vezes você não precisa de tudo, mas apenas de tipos específicos de arquivos. Vamos implementar a filtragem usando strings.HasSuffix e a verificação IsDir()