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:
- Abrir o ficheiro
- Ler/escrever o ficheiro
- 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)
O 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:
- Gestão automático de recursos: Evita vazamento de memória ou recursos não libertados.
- Código mais limpo e seguro: Substitui a necessidade de usar blocos
try-finally
para libertar recursos manualmente. - 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 abertura | Descrição |
---|---|
r | Abre o ficheiro sómente para leitura. O apontador do ficheiro é posicionado no início do ficheiro. Este é o modo de abertura de defeito. |
rb | Abre 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. |
w | Abre 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. |
wb | Abre 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. |
a | Abre 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. |
ab | Abre 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
O objeto_de_ficheiro retornado pela função open(), possui os seguintes atributos:
Atributo | Descrição |
---|---|
objeto_de_ficheiro.closed | Retorna True se o ficheiro estiver fechado, False no caso contrário. |
objeto_de_ficheiro.mode | Retorna o modo de abertura com que o ficheiro foi aberto. |
objeto_de_ficheiro.name | Retorna o nome do ficheiro. |
Ficheiros de texto
Ler ficheiro de texto
Para lermos um ficheiro de texto, temos os métodos abaixo:
Método | Descriçã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étodo | Descriçã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()