Lendo arquivo linha por linha em Go: melhores práticas 2025

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

Lendo arquivo linha por linha em Go: do iniciante ao profissional em 2025

\n\n

Você já se perguntou como ler eficientemente arquivos de log enormes ou processar dados CSV em Go? Se sim, você veio ao lugar certo. O tema da leitura de arquivos linha por linha é um dos mais populares no Stack Overflow, e não é por acaso. Go nos dá ferramentas poderosas, mas escolher a abordagem certa às vezes não é fácil.

\n\n

Neste artigo, não vamos apenas mostrar como ler linhas de um arquivo. Vamos analisar as melhores práticas de 2025: desde o rápido bufio.Scanner até soluções bufferizadas personalizadas. Você aprenderá como evitar armadilhas (por exemplo, linhas com mais de 64KB), tratar erros corretamente e acelerar o trabalho com grandes volumes de dados.

\n\n

Pronto? Vamos lá!

\n\n

Por que ler linhas não é simplesmente "pegar e ler"?

\n\n

Em Go, existem várias maneiras de ler arquivos, e cada uma é para uma tarefa específica. Alguns usam ioutil.ReadFile (aliás, desde Go 1.16 ele está deprecated), outros usam os.File com buffer. Mas para processamento linha por linha, o rei é bufio.Scanner.

\n\n

Por quê? Porque ele:

\n
    \n
  • É eficiente em memória — não carrega o arquivo inteiro na RAM
  • \n
  • É simples de usar — mínimo de código
  • \n
  • Sabe tratar erros — verifica cada etapa
  • \n
\n\n

Mas há um detalhe: o buffer padrão do Scanner é de 64 KB. Se sua linha for maior — você receberá um erro. Para esses casos, são necessárias outras abordagens.

\n\n

Exemplo básico: bufio.Scanner

\n\n

Vamos começar com a maneira mais comum. Aqui está o código funcional mínimo:

\n\n
package main\n\nimport (\n    "bufio"\n    "fmt"\n    "log"\n    "os"\n)\n\nfunc main() {\n    file, err := os.Open("data.txt")\n    if err != nil {\n        log.Fatal(err)\n    }\n    defer file.Close()\n\n    scanner := bufio.NewScanner(file)\n    for scanner.Scan() {\n        line := scanner.Text()\n        fmt.Println(line)\n    }\n\n    if err := scanner.Err(); err != nil {\n        log.Fatal(err)\n    }\n}\n
\n\n

O que é importante aqui?

\n
    \n
  • defer file.Close() — fecha o arquivo mesmo em caso de pânico
  • \n
  • scanner.Text() — retorna a linha sem o caractere de nova linha (\\n)
  • \n
  • scanner.Err() — verifica se houve erros durante a leitura
  • \n
\n\n

Este código é ideal para 90% das tarefas: configurações, logs, CSV pequenos.

\n\n

Problema de linhas longas: aumentando o buffer

\n\n

Imagine: você está lendo um arquivo com linhas JSON de 100 KB. O Scanner falhará com o erro bufio.Scanner: token too long. A solução é aumentar o buffer:

\n\n
scanner := bufio.NewScanner(file)\nbuf := make([]byte, 0, 1024*1024) // 1 MB\nscanner.Buffer(buf, 10*1024*1024) // máximo de 10 MB por linha\n\nfor scanner.Scan() {\n    // ... processamento\n}\n
\n\n

Importante: o segundo parâmetro é o tamanho máximo da linha. Se a linha for maior — erro novamente. Escolha com margem, mas não gigantesca — a memória não é elástica.

\n\n

Quando o Scanner não é adequado: alternativas

\n\n

Apesar da popularidade, bufio.Scanner não é universal. Aqui estão dois casos em que vale a pena considerar outra abordagem:

\n\n

1. Arquivos enormes (gigabytes)

\n

Se o arquivo for maior que a memória disponível (raro, mas acontece), o Scanner ainda é bom. Mas se você precisa ler dados binários ou processar linhas com delimitadores personalizados — é melhor usar bufio.Reader:

\n\n
reader := bufio.NewReader(file)\nfor {\n    line, err := reader.ReadString('\\n')\n    if err != nil {\n        break\n    }\n    // line contém \\n no final\n    line = strings.TrimRight(line, "\\n")\n    fmt.Println(line)\n}\n
\n\n

Vantagem: você controla cada operação de leitura. Desvantagem: mais código e maior risco de erros.

\n\n

2. Processamento sem carregar na memória

\n

Às vezes, você só precisa contar linhas ou encontrar um padrão. Para isso, bufio.Scanner é adequado

Blogs

Book Recommendations