W3docs

Leitura de Arquivos em Python – Guia Completo

Aprenda todas as formas de ler arquivos em Python: read(), readline(), readlines(), iteração por linha, modo binário, codificação e pathlib.

Ler arquivos é uma das tarefas mais comuns em Python — seja para carregar configurações, processar logs, importar dados CSV ou ler recursos binários. Este capítulo abrange todos os métodos que Python oferece para ler conteúdo de arquivos: desde a chamada mais simples com read() até a iteração linha a linha com eficiência de memória, modo binário, tratamento de codificação, controle de posição no arquivo e a API moderna do pathlib.

Abrindo um Arquivo para Leitura

Toda operação com arquivos começa com a função embutida open(). Para abrir um arquivo no modo de leitura, use a string de modo "r" (que é o padrão quando nenhum modo é especificado):

file_object = open("notes.txt", "r", encoding="utf-8")
  • "r" — abre para leitura; levanta FileNotFoundError se o arquivo não existir.
  • encoding="utf-8" — sempre especifique a codificação de caracteres para arquivos de texto para que seu código funcione de forma idêntica no Windows, macOS e Linux.

Sempre Use um Bloco with

A maneira mais segura de abrir um arquivo é dentro de uma instrução with. Python fecha automaticamente o arquivo quando o bloco termina — mesmo que ocorra uma exceção — o que evita vazamentos de recursos e garante que quaisquer dados em buffer sejam descarregados.

with open("notes.txt", "r", encoding="utf-8") as f:
    contents = f.read()
# File is automatically closed here

Chamar open() fora de um bloco with e esquecer file.close() é uma fonte frequente de erros de "too many open files" em scripts de longa execução.

Lendo o Arquivo Inteiro com read()

read() retorna o conteúdo completo do arquivo como uma única string.

Ler um arquivo inteiro de uma vez

with open("notes.txt", "r", encoding="utf-8") as f:
    contents = f.read()

print(contents)

Use read() quando:

  • O arquivo for pequeno o suficiente para caber confortavelmente na memória.
  • Você precisar do texto completo como uma string (por exemplo, para análise ou busca).

Para arquivos que possam ser grandes (logs, dumps de dados), prefira as abordagens linha a linha descritas abaixo.

Ler um Número Fixo de Caracteres

Passe um inteiro n para read(n) para ler no máximo n caracteres a partir da posição atual. Chamadas subsequentes a read(n) continuam de onde a última leitura parou.

Ler os primeiros 50 caracteres

with open("notes.txt", "r", encoding="utf-8") as f:
    first_chunk = f.read(50)
    second_chunk = f.read(50)

print(repr(first_chunk))
print(repr(second_chunk))

Essa abordagem em blocos é útil quando você quer visualizar um arquivo ou processá-lo em pedaços de tamanho fixo sem carregar tudo na memória.

Lendo Uma Linha por Vez com readline()

readline() lê uma linha do arquivo, incluindo o caractere de nova linha \n no final. Retorna uma string vazia "" quando o fim do arquivo é alcançado, o que facilita o loop até o EOF.

Ler um arquivo linha por linha com readline()

with open("notes.txt", "r", encoding="utf-8") as f:
    line = f.readline()
    while line:
        print(line, end="")   # line already contains '\n'
        line = f.readline()

O argumento end="" em print() evita que apareça uma linha dupla em branco (uma da linha do arquivo e outra do padrão do print).

readline() é útil quando você precisa processar uma linha de cabeçalho de forma diferente do restante, ou quando deseja parar a leitura no meio do arquivo com base em uma condição.

Iterando Sobre as Linhas (Modo Mais Pythônico)

Iterar diretamente sobre um objeto de arquivo é a forma mais idiomática e eficiente em memória de processar um arquivo de texto linha a linha. Python lê uma linha por vez sem carregar o arquivo inteiro na memória.

Iterar sobre linhas com um loop for

with open("notes.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line, end="")

Esse padrão é preferível ao read() + split("\n") e à chamada de readline() em um loop while, pois é mais curto e trata corretamente todos os casos extremos (incluindo arquivos que não terminam com uma nova linha).

Buscar um padrão durante a iteração

with open("server.log", "r", encoding="utf-8") as f:
    for line in f:
        if "ERROR" in line:
            print(line, end="")

Lendo Todas as Linhas em uma Lista com readlines()

readlines() retorna uma lista em que cada elemento é uma linha do arquivo (com o caractere de nova linha incluído). Isso carrega o arquivo inteiro na memória.

Ler todas as linhas em uma lista

with open("notes.txt", "r", encoding="utf-8") as f:
    lines = f.readlines()

print(lines[0])        # first line
print(lines[-1])       # last line
print(len(lines))      # total number of lines

Use readlines() quando precisar de acesso aleatório a linhas específicas por índice. Para processamento sequencial de cima para baixo, o padrão for line in f é mais eficiente em memória.

Remover Caracteres de Nova Linha

As linhas retornadas por readline(), readlines() e pela iteração com for incluem o \n no final. Use .strip() ou .rstrip("\n") para removê-lo:

with open("notes.txt", "r", encoding="utf-8") as f:
    lines = [line.rstrip("\n") for line in f]

print(lines)  # ['Line one', 'Line two', 'Line three']

Escolhendo o Método de Leitura Correto

MétodoRetornaCarrega o arquivo inteiro?Melhor para
f.read()strSimArquivos pequenos, análise de texto completo
f.read(n)strNão (em blocos)Streaming em tamanho fixo
f.readline()strNãoParadas condicionais linha a linha
for line in fstr (um por iteração)NãoProcessamento sequencial de linhas
f.readlines()list[str]SimAcesso aleatório por índice às linhas

Posição no Arquivo: tell() e seek()

Todo objeto de arquivo aberto mantém um ponteiro de posição interno que avança conforme você lê. Dois métodos permitem inspecionar e controlar esse ponteiro:

  • tell() — retorna o deslocamento de bytes atual a partir do início do arquivo.
  • seek(offset, whence=0) — move o ponteiro. Com whence=0 (padrão), o deslocamento é a partir do início; whence=1 é a partir da posição atual; whence=2 é a partir do final.

Ler um arquivo duas vezes usando seek(0)

with open("notes.txt", "r", encoding="utf-8") as f:
    first_pass = f.read()
    print(f"Position after first read: {f.tell()}")

    f.seek(0)   # rewind to the beginning
    second_pass = f.read()

print(first_pass == second_pass)  # True

seek() é particularmente útil no modo "r+" (leitura e escrita), onde você pode ler uma seção do arquivo e depois sobrescrever uma parte específica na mesma chamada open().

Tratando Erros ao Ler Arquivos

Um script bem escrito sempre antecipa as formas pelas quais uma leitura de arquivo pode falhar.

Tratar erros comuns de leitura

try:
    with open("data.txt", "r", encoding="utf-8") as f:
        content = f.read()
except FileNotFoundError:
    print("Error: the file does not exist.")
except PermissionError:
    print("Error: you do not have permission to read this file.")
except UnicodeDecodeError:
    print("Error: the file contains bytes that are not valid UTF-8.")
except OSError as e:
    print(f"OS error: {e}")

Exceções comuns que você vai encontrar:

ExceçãoQuando ocorre
FileNotFoundErrorO caminho não aponta para um arquivo existente
PermissionErrorO processo não tem permissão de leitura
IsADirectoryErrorO caminho aponta para um diretório, não para um arquivo
UnicodeDecodeErrorOs bytes do arquivo não correspondem à codificação especificada

Consulte Python Try Except para um guia completo sobre tratamento de exceções.

Codificação de Caracteres

Quando Python abre um arquivo no modo texto, ele precisa saber como converter bytes brutos em caracteres. Sempre passe encoding= explicitamente em vez de depender do padrão da plataforma, que difere entre Windows (cp1252) e a maioria dos sistemas Unix (utf-8).

Valores de codificação comuns:

CodificaçãoUse quando
"utf-8"Arquivos modernos, conteúdo web, a maioria dos projetos Python
"utf-8-sig"Arquivos UTF-8 criados por ferramentas do Windows que adicionam um BOM
"latin-1"Arquivos legados do Oeste Europeu
"cp1252"Arquivos de texto ANSI do Windows

Detectar ou ignorar problemas de codificação:

Se você não tiver certeza sobre a codificação de um arquivo, pode instruir Python a substituir bytes não decodificáveis por um marcador em vez de gerar um erro:

with open("mystery.txt", "r", encoding="utf-8", errors="replace") as f:
    content = f.read()

Outros valores para errors incluem "ignore" (ignorar bytes inválidos silenciosamente) e "strict" (padrão — levanta UnicodeDecodeError).

Lendo Arquivos Binários

Abra um arquivo no modo binário adicionando "b" à string de modo ("rb"). O modo binário retorna objetos bytes brutos em vez de strings, o que é correto para imagens, áudio, arquivos compactados, executáveis e quaisquer dados não textuais.

Ler um arquivo binário

with open("photo.jpg", "rb") as f:
    data = f.read()

print(type(data))   # <class 'bytes'>
print(len(data))    # size in bytes

Copiar um arquivo binário

with open("photo.jpg", "rb") as src:
    data = src.read()

with open("photo_backup.jpg", "wb") as dst:
    dst.write(data)

Não especifique encoding no modo binário — Python levanta ValueError se você tentar.

Lendo Arquivos Grandes com Eficiência

Carregar um arquivo de vários gigabytes com read() pode esgotar a memória do sistema. As soluções são:

Iteração linha a linha (arquivos de texto)

with open("huge_log.txt", "r", encoding="utf-8") as f:
    for line in f:
        process(line)   # only one line in memory at a time

Blocos de tamanho fixo (arquivos binários)

CHUNK_SIZE = 65536  # 64 KB

with open("large_file.bin", "rb") as f:
    while True:
        chunk = f.read(CHUNK_SIZE)
        if not chunk:
            break
        process(chunk)

Ambos os padrões mantêm o uso de memória constante independentemente do tamanho do arquivo.

Lendo Arquivos com pathlib

Python 3.4 introduziu pathlib.Path, que fornece uma interface orientada a objetos para caminhos do sistema de arquivos. Para leituras e escritas simples de uma única vez, objetos Path são mais concisos do que open().

Ler texto com Path.read_text()

from pathlib import Path

content = Path("notes.txt").read_text(encoding="utf-8")
print(content)

Ler bytes com Path.read_bytes()

from pathlib import Path

data = Path("photo.jpg").read_bytes()
print(len(data))  # file size in bytes

read_text() e read_bytes() abrem o arquivo, leem todo o seu conteúdo e o fecham em uma única chamada. Use-os para arquivos pequenos quando você só precisa do conteúdo. Use open() com um bloco with quando precisar de iteração linha a linha, leitura em blocos, seek() ou qualquer outro controle mais refinado.

Verificar Se um Arquivo Existe Antes de Ler

from pathlib import Path

p = Path("data.txt")
if p.exists() and p.is_file():
    content = p.read_text(encoding="utf-8")
else:
    print("File not found.")

Observação: p.exists() pode retornar um resultado obsoleto em código multi-thread. Nesses casos, é mais seguro tentar a leitura e capturar FileNotFoundError.

Exemplo Prático: Lendo um Arquivo de Configuração Simples

Muitos scripts leem um arquivo de configuração em texto simples que armazena um par chave=valor por linha. Aqui está um exemplo completo e funcional:

Analisar um arquivo de configuração chave=valor

from pathlib import Path

def load_config(path):
    config = {}
    with open(path, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith("#"):
                continue          # skip blank lines and comments
            key, _, value = line.partition("=")
            config[key.strip()] = value.strip()
    return config

# Example config.txt contents:
# host = localhost
# port = 8080
# debug = true

config = load_config("config.txt")
# config == {'host': 'localhost', 'port': '8080', 'debug': 'true'}

str.partition("=") divide na primeira = apenas, de modo que valores que contenham = (como strings Base64) são tratados corretamente.

Capítulos Relacionados

Was this page helpful?