Este tutorial fala sobre o ponto básico para se iniciar a manipulação de arquivos binários com Python. É bem básico, mas espero que gostem:
Vamos começar analisando uma estrutura.
import sys #Importa o módulo sys => exit try: arquivo = open("arquivo.exe","rb") print "Arquivo aberto!" arquivo.close() sys.exit(0) except IOError: print "Erro ao abrir o arquivo" sys.exit(1)
Antes de tudo, já sabe que o modo rb tenta abrir um arquivo como binário para leitura. Reveja a tabela:
Parâmetro | Acção |
---|---|
rb | Abre um arquivo binário especificado para leitura. O arquivo deve existir previamente. |
wb | Abre um arquivo binário especificado para escrita. Caso o arquivo não exista, este será criado, porém , caso exista, seus dados serão sobrescritos. |
r+b | Abre um arquivo binário especificado para leitura e escrita. O arquivo deve existir previamente, podendo ser alterado. |
w+b | Abre um arquivo binário especificado para escrita e leitura. Caso o arquivo não exista será criado, caso exista, seus dados serão sobrescritos. |
a+b | Abre um arquivo binário especificado no modo Append. Caso o arquivo não exista, será criado, caso exista, os dados serão acrescentados após a sua última linha, não sobrescrevendo-o. |
Na estrutura acima, utilizamos dois métodos: try e except. O método try, como a sua própria tradução sugere (tentar), tenta executar uma ou mais ações que podem não ser executadas com sucesso. O método except, é utilizado justamente para validar os possíveis erros que impediram as instruções especificadas por try de serem finalizadas com êxito.
Utilizamos IOError para validar erros de entrada/saída, consequentemente, a manipulação de arquivos. Voltando à estrutura, o programa tenta abrir o arquivo, e em caso de erro, é retornada uma mensagem de erro. Para fecharmos um arquivo, utilizamos: arquivo.close().
Abaixo temos um exemplo de como retornar o tamanho de um arquivo:
import sys try: arquivo = open("arquivo.exe","rb") except IOError: print "Erro ao abrir o arquivo" sys.exit(1) arquivo.seek(0,2) tamanho = arquivo.tell() print "O tamanho do arquivo e:",tamanho arquivo.close() sys.exit(0)
Veja: arquivo.seek(0,2) ⇒ A função arquivo.seek() é utilizada para alterar a posição read/write do código de um arquivo.
A sintaxe da função é: arquivo.seek(bloco,[origem])
bloco ⇒ Número de bytes para o qual a posição read/write será alterada a partir da origem. origem ⇒ Define a posição de onde o bloco de bytes será contado.
Embora seja opcional especificar a origem, para esta, temos:
Valor | Posição |
---|---|
0 | Início do arquivo |
1 | Posição actual |
2 | Final do Arquivo |
Portanto, no trecho: arquivo.seek(0,2); estamos alterando a posição read/write exatamente para o final do arquivo. E como já sabemos, a última posição de leitura/escrita em um arquivo, indica o tamanho do arquivo em bytes.
tamanho = arquivo.tell() ⇒ Atribuimos à variável tamanho, o valor de retorno da função arquivo.tell() que retorna a posição atual de leitura/escrita no arquivo.
Considere o código:
# Exemplo: Lendo um arquivo inteiro. import sys try: arquivo = open("arquivo.exe","rb") except IOError: print "Erro ao abrir o arquivo" sys.exit(1) arquivo.seek(0,2) tamanho = arquivo.tell() arquivo.seek(0) buffer = arquivo.read(tamanho) arquivo.close() sys.exit(0)
Analisando: arquivo.seek(0) ⇒ Retorna a posição read/write ao início, para podermos ler o arquivo desde o início. buffer = arquivo.read(tamanho) ⇒ Amarzena em um buffer todo o conteúdo do arquivo.
A sintaxe da função é: buffer arquivo.read(tamanho)
buffer ⇒ Buffer no qual o conteúdo será lido. tamanho ⇒ Tamanho em bytes do bloco a ser lido.
Considere agora o código que lê o arquivo por partes:
#Exemplo: lendo um arquivo por partes import sys try: arquivo = open("arquivo.exe","rb") except IOError: print "Erro ao abrir o arquivo" sys.exit(1) arquivo.seek(0,2) tamanho = arquivo.tell() arquivo.seek(0) chunk = 1024 while arquivo.tell() < tamanho: buffer = arquivo.read(chunk) print "Posicao:",arquivo.tell()," - Total:",tamanho arquivo.close() sys.exit(0)
Destacando: chunk = 1024 ⇒ Atribuimos a uma variável denominada chunk o valor 1024, que representa o número de bytes a serem lidos por vez. while arquivo.tell() < tamanho: ⇒ Enquanto a posição read/write não for a última. buffer = arquivo.read(chunk) ⇒ Lê no arquivo,o tamanho especificado pelo chunk, no caso, 1024 bytes. print "Posicao:",arquivo.tell()," - Total:",tamanho ⇒ Mostra a posição read/write atual do arquivo e o tamanho do arquivo, a cada loop.
Em Python, o tamanho disponível para ser lido (diferença entre posição read/write final e posição read/write atual) é automaticamente calculado.
Veremos agora como escrever em arquivos binários:
# Exemplo: escrevendo em um arquivo import sys try: arquivo = open("arquivo.exe","wb") except IOError: print "Erro ao abrir o arquivo" sys.exit(1) arquivo.write("hi") arquivo.close() sys.exit(0)
Explicando: arquivo = open("arquivo.exe","wb") ⇒ Utilizamos o modo wb ao invés de rb; arquivo.write("hi") ⇒ A função arquivo.write() é a função inversa à arquivo.read(). Enquanto a última ler dados, arquivo.write() escreve.
Sintaxe: arquivo.write(buffer) buffer ⇒ Buffer que contém os dados a serem escritos.
Considere o código que lê um arquivo por inteiro em seguida escreve um arquivo com os dados lidos:
# Exemplo: lendo e escrevendo em um arquivo inteiro; import sys try: arquivo = open("arquivo.exe","rb") destino = open("copia.exe","wb") except IOError: #Erro ao abrir algum dos arquivos print "Erro ao abrir o arquivo" sys.exit(1) arquivo.seek(0,2) tamanho = arquivo.tell() arquivo.seek(0) buffer = arquivo.read(tamanho) destino.write(buffer) arquivo.close() destino.close() sys.exit(0)
Pontos em destaque: arquivo = open("arquivo.exe","rb") ⇒ Abre o arquivo de origem para leitura. destino = open("copia.exe","wb") ⇒ Abre o arquivo de destino para escrita. buffer = arquivo.read(tamanho) ⇒ Lê o conteúdo do arquivo de origem. destino.write(buffer) ⇒ Escreve no arquivo de destino o conteúdo lido. arquivo.close() destino.close() ⇒ Fecha os arquivos.
Abaixo, segue o código que como realizar tal processo, porém lendo e escrevendo um arquivo por partes.
# Exemplo: lendo e escrevendo em um arquivo inteiro; import sys try: arquivo = open("arquivo.exe","rb") destino = open("copia.exe","wb") except IOError: print "Erro ao abrir o arquivo" sys.exit(1) arquivo.seek(0,2) tamanho = arquivo.tell() arquivo.seek(0) chunk = 1024 while arquivo.tell() < tamanho: buffer = arquivo.read(chunk) destino.write(buffer) arquivo.close() destino.close() sys.exit(0)
Acima notamos que a cada loop o programa tenta ler 1024 bytes do arquivo ou então lê a quantidade total disponível, em seguida, escreve esses bytes no arquivo de destino.