Tratamento de ficheiros

A manipulação de ficheiros é essencial em Python para ler, escrever e modificar dados persistentes.

O Python permite escrever/ler ficheiros em disco no sistema de ficheiros. Tal é feito através de funções de sistema, sem necessidade de recorrer a qualquer módulo.

Tipos de ficheiros

Os ficheiros em disco são de dois tipos: ficheiros de texto ou ficheiros binários.

  • Um ficheiro de texto é um ficheiros com carateres organizados em linhas.
  • Um ficheiro binário são todos os ficheiros que não são de texto. Cada ficheiro binário tem uma estrutura própria que é conhecido da aplicação que o abre.

No caso de ficheiros de texto podemos considerar dois tipos de ficheiros especiais: ficheiros JSON e ficheiros CSV.

Fases do tratamento de ficheiros

A manipulação de ficheiros envolve 3 passos:

  1. Abrir o ficheiro
  2. Ler/escrever o ficheiro
  3. Fechar o ficheiro

Devemos fechar sempre o ficheiro após o termos usado.

Exemplo:

# Abre ficheiro para escrita, em modo texto:
f = open("doc.txt", "w")

# Escreve texto no ficheiro:
f.write( "Estou a gostar de aprender Python\n")

# Fecha o ficheiro
f.close()

Gestor de contexto (with)

gestor de contexto em Python é uma ferramenta que facilita a gestão de recursos, como ficheiros, conexões de base de dados de dados ou sockets, garantindo que eles sejam configurados e libertados corretamente, mesmo em caso de erros ou exceções. Ele é usado em conjunto com a instrução with, que cria um “bloco de contexto” para executar operações específicas.

Se usarmos o gestor de contexto (with) não temos de, explicitamente, fechar o ficheiro com o método close().

Exemplo:

with open('ficheiro.txt', 'r') as fich:
    conteudo = fich.read()
# O ficheiro é fechado automaticamente aqui

Beneficios do uso do gestor de contexto:

  1. Gestão automático de recursos: Evita vazamento de memória ou recursos não libertados.
  2. Código mais limpo e seguro: Substitui a necessidade de usar blocos try-finally para libertar recursos manualmente.
  3. Tratamento robusto de exceções: Recursos são libertados mesmo em caso de erro dentro do bloco.

Abrir um ficheiro

Antes que se possa ler ou escrever um ficheiro temos de o abrir. O Python oferece a função de sistema open() para esse efeito.

Sintaxe:

objeto_de_ficheiro = open(nome_ficheiro [, modo_acesso][, armazenamento_em_buffer])

objeto_de_ficheiro é um objeto retornado pela função função, caso a abertura do ficheiro seja bem sucedida. Se não for uma exceção do tipo OSError é levantada.

O objeto objeto_de_ficheiro possui um conjunto de métodos que nos permitem manipular o ficheiro (ler, escrever, fechá-lo…).

modo de acesso especifica o modo como o ficheiro é aberto (leitura, escrita, append, etc..). A lista completa dos modos de acesso é dada na tabela abaixo. Este argumento é opcional e se não for fornecido o modo de abertura será ‘r’ (leitura).

armazenamento_em_buffer argumento opcional. Se o valor for 0, não vai haver armazenamento em buffer. Se o valor for 1, o armazenamento será feito por linha. Se o valor for maior que 1 esse valor especifica o tamanho do buffer. Se o valor for negativo, o tamanho do buffer será o definido no sistema como defeito.

Modo de aberturaDescrição
rAbre o ficheiro sómente para leitura. O apontador do ficheiro é posicionado no início do ficheiro. Este é o modo de abertura de defeito.
rbAbre o ficheiro sómente para leitura em binário. O apontador do ficheiro é posicionado no início do ficheiro.
r+Abre o ficheiro sómente para leitura e escrita. O apontador do ficheiro é posicionado no início do ficheiro.
rb+Abre o ficheiro sómente para leitura e escrita em binário. O apontador do ficheiro é posicionado no início do ficheiro.
wAbre o ficheiro sómente para escrita. Reescreve o ficheiro se o ficheiro existir. Se o ficheiro não existir, cria um novo ficheiro para escrita.
wbAbre o ficheiro sómente para escrita em binário. Reescreve o ficheiro se o ficheiro existir. Se o ficheiro não existir, cria um novo ficheiro para escrita.
w+Abre o ficheiro sómente para leitura e escrita. Reescreve o ficheiro se o ficheiro existir. Se o ficheiro não existir, cria um novo ficheiro para leitura e escrita.
wb+Abre o ficheiro sómente para leitura e escrita em binário. Reescreve o ficheiro se o ficheiro existir. Se o ficheiro não existir, cria um novo ficheiro para leitura e escrita.
aAbre o ficheiro para append. O apontador do ficheiro é posicionado no fim do ficheiro se o ficheiro existir. O ficheiro fica em modo append. If the file does not exist, it creates a new file for writing.
abAbre o ficheiro para append em binário. O apontador do ficheiro é posicionado no fim do ficheiro se o ficheiro existir. O ficheiro fica em modo append. Se o ficheiro não existir, cria um novo ficheiro para escrita.
a+Abre o ficheiro sómente para leitura e append. O apontador do ficheiro é posicionado no fim do ficheiro se o ficheiro existir. O ficheiro fica em modo append. Se o ficheiro não existir, cria um novo ficheiro para leitura e escrita.
ab+Abre o ficheiro somente para leitura e append em binário. O apontador do ficheiro é posicionado no fim do ficheiro se o ficheiro existir. O ficheiro fica em modo append. Se o ficheiro não existir, cria um novo ficheiro para leitura e escrita.

Atributos do objeto de ficheiro

objeto_de_ficheiro retornado pela função open(), possui os seguintes atributos:

AtributoDescrição
objeto_de_ficheiro.closedRetorna True se o ficheiro estiver fechado, False no caso contrário.
objeto_de_ficheiro.modeRetorna o modo de abertura com que o ficheiro foi aberto.
objeto_de_ficheiro.nameRetorna o nome do ficheiro.

Ficheiros de texto

Ler ficheiro de texto

Para lermos um ficheiro de texto, temos os métodos abaixo:

MétodoDescrição
.read()Lê todo o conteúdo como string.
.readline()Lê uma linha por vez.
.readlines()Retorna uma lista com todas as linhas.

Exemplo 1:

# Abre ficheiro para leitura, em modo texto:
with open("doc.txt", "r") as f:
    # Lê até 23 carateres do ficheiro:
    texto = f.read(23)
    print ("Texto : ", texto)

Exemplo 2:

with open("dados.txt") as f:
    #Lê todo o ficheiro, linha a linha
    while True:
        line = f.readline()
        if not line:
            break
        print(line)

Exemplo 3:

with open("dados.txt") as f:
    lines = f.readlines()
    for line in lines:
        print(line)

Escrever ficheiro de texto

Podemos escrever dados num ficheiro de texto com os métodos abaixo:

MétodoDescrição
.write()Escreve texto no ficheiro.
.writelines()Escreve items de uma lista num ficheiro..

Exemplo 1:

with open("dados.txt", "w") as f:
    f.write("Olá, Python!\n")  # Escreve uma linha

Exemplo 2:

linhas = ["Linha 1\n", "Linha 2\n"]
with open("lista.txt", "w") as f:
    f.writelines(linhas)  # Escreve múltiplas linhas

Ficheiros binários

Ler ficheiro binário

Lemos um ficheiro binário com o método read().

Exemplo 1:

with open('dados.bin', 'rb') as file:
    dados = file.read()

No exemplo acima, a função read() lê todo o conteúdo do ficheiro.

Exemplo 2:

with open('dados.bin', 'rb') as file:
    dados = file.read(4) # lê 4 bytes do ficheiro

Escrever ficheiro binário

Escrevemos num ficheiro binário com o método write():

dados = b'\x48\x65\x6c\x6c\x6f'  # Exemplo de bytes
with open('saida.bin', 'wb') as file:
    file.write(dados)

Posicionamento do apontador de posição

O apontador de posição retém a posição de leitura e escrita dentro do ficheiro. A leitura de dados de um ficheiro é feita sempre a partir da posição indicada pelo apontador de posição, assim como a escrita de dados é feita a partir dessa posição.

O método tell()

O método tell() retorna a posição corrente do apontador de posição, contada a partir do inicio do ficheiro.

O método seek()

O método seek() permite-nos movimentar o apontador de posição ao longo do ficheiro.

Sintaxe:

objeto_de_ficheiro.seek(deslocamento [, de])

deslocamento: indica o número de caracteres ou bytes do deslocamento do apontador de posição.

de: indica a posição a partir da qual se vai efetuar o deslocamento do apontador de posição. Se o seu valor for 0 o deslocamento é feito a partir do início do ficheiro; se for 1, é feito a partir da posição corrente; se for 2 é feito a partir do fim do ficheiro.

Exemplo:

# Abre o ficheiro para leitura
f = open("doc.txt", "r")
texto = f.read(10)
print ("Read String is : ", texto)

# Verifica a posição currente do apontador de posição
pos = f.tell()
print ("Apontador de posição : ", pos)

# Reposiona o apontador de posição para o início do ficheiro
pos = f.seek(0, 0)
texto = f.read(10)
print ("Again read String is : ", texto)

# Close opened file
f.close()