Lendo, escrevendo e organizando arquivos


Lendo, escrevendo e organizando arquivos

Arquivos

No nivel mais básico, de bits e bytes, arquivos são coleções de bits binários armazenados em disco ou na memória de computadores.
O tipo de arquivos passa a ter relevância na hora de ler seu conteúdo ou adicionar conteúdo. Assim um arquivo texto (terminação .txt) contem bits tal qual um arquivo binário executável (terminação .exe), não sendo legivel por ser humano na forma como está guardadado.
Para lêr o arquivo texto como tal é preciso informar o programa leitor qual tipo de leitura queremos e ele então vai decodificar os bits lidos em letras, pontuação, etc resultando num texto legivel por ser humano.
Se tentarmos ler um arquivo binário executável como se fosse um texto a decodificação não vai funcionar e uma mistura de simbolos sem sentido será "lida". Tal tipo de arquivo não é criado para ser lido como texto mas sim para ser carregado em formato binário de programa executável pelo computador.
Por outro lado se queremos manipular um arquivo binário devemos informar isto para o programa leitor ou escritor.
Para complicar mais as coisas há textos e textos. Originalmente computação era quase exclusivamente feita na lingua inglêsa. Para cobrir todas as letras e simbolos usados em inglês bastavam 128 conjuntos de 8 bits (byte) por caracter. Este forma de codificar alfabeto em bits era chamada Código ASCII (American Standard Code for Information Interchange).
Com a disseminação rápida da Ciência de Computação pelo mundo logo surgiu necessidade de codificar alfabetos com outros numeros de letras e simbolos. Para tanto passaram a ser criados diversos outros códigos e padrões, numa grande e confusa mistura. Isto é assunto para outra ocasião mas uma ótima apresentação está aqui.
Como exemplo aqui está um texto que guardamos em arquivo tipo .txt:
A Ciência Política surgiu como disciplina e instituição em meados do século XIX, período em que avançou como "Ciência do Estado" principalmente na Alemanha, Itália e França. De maneira mais ampla, a Ciência Política pode ser entendida como a disciplina que se volta para o estudo de qualquer fenômeno ligado às estruturas políticas de maneira sistemática, sempre apoiado na observação empírica rigorosa e fundamentado em argumentos racionais. Nesse sentido, a palavra "ciência" é usada como ideia oposta à noção de "opinião", de forma que, como Noberto Bobbio* esclarece em seu Dicionário de Política, "ocupar-se cientificamente de política significa não se abandonar a opiniões e crenças do vulgo, não formular juízos com base em dados imprecisos, mas apoiar-se nas provas dos fatos."
Usamos um programa especial capaz de mostrar o conteudo binário básico de um arquivo em disco (frhed.exe). Abrindo nosso arquivo texto original com este programa obtemos a janela mostrada abaixo na figura:
alt text
Nesta figura a tabela cheia de numeros e letras no lado esquerdo é a imagem fiel do conteúdo de nosso arquivo texto como armazenado em disco (na verdade está apresentado em formato hexadecimal e não binário para ocupar menos espaço).
A parte com texto truncado na direita é o que este programa decodificou como texto correspondente ao conteúdo binário. Claramente muitas letras originais foram substituidas por simbolos estranhos no texto. Isto ocorreu porque o programa leitor decodificou os bits em código OEM (um ASCII extendido) e as letras portuguesas que não tem correspondente em inglês foram decodificadas como tais simbolos esquisitos.
Em resumo, ao lermos ou escrevermos conteúdo de arquivos devemos informar o programa usado qual tipo de arquivo queremos usar (o default usualmente é texto) e ainda no caso de textos, qual a codfificação de caracteres vamos usar (usualmente é UTF-8, mas isto varia muito e depende do computador, etc).

Lendo e escrevendo arquivos

Arquivos são salvos em disco de acordo com um esquema de organização de pastas (diretórios) que constitue o assim chamado file system. Todo arquivo é sempre salvo dentro de alguma pasta (ou diretório) no file system.
Para localizar um arquivo existe um caminho (path) que parte da pasta hierarquicamente mais alta descendo por pastas subalternas até chegar na pasta do arquivo. A pasta mais alta usualmente será o nome de alguma unidade de disco do computador, por exemplo a letra C designa a unidade normalmente usada em quase todo computador com Windows.
Podemos dizer que todo arquivo em disco tem duas propriedades essenciais:
  • um nome tal como "dados.txt" (filename)
  • um caminho para localiza-lo tal como "C:\desktop\dados.txt" (path)
No caminho "C:\desktop\dados.txt" as barras para esquerda () significam descer para subdiretório seguinte e por ultimo o nome do arquivo. Ou seja, C => desktop => dados.txt
Para chegar até o diretório desejado usaremos o módulo os, utilissimo. Duas funções uteis deste módulo permitem achar o caminho do diretório corrente onde está executando o programa e mudar do diretório corrente para algum outro cujo caminho for dado:
  • os.getcwd() retorna string com diretório corrente
  • os.chdir(um_caminho) muda diretório corrente para "um_caminho"
In [10]:
import os
s = os.getcwd()
print(s)
os.chdir('C:\\')
print(os.getcwd())
os.chdir(s)
C:\Users\ps\Desktop\Blog
C:\
Para ver uma lista com todo conteúdo de um diretório usa-se a função
  • os.listdir()
In [12]:
os.chdir(r'C:\\Users\\ps\\Desktop\\Blog\\lixo')
os.listdir()
Out[12]:
['cienciapolitica.txt', 'cp.txt', 'dep1.xlsx']
Ocasionalmente é necessário criar novos diretórios. Para tanto o módulo os tem a função
  • os.makedirs('um_caminho_onde_criar_novo_diretorio')
In [13]:
s = os.getcwd()
print(s)
s1 = s + r'\lixo1'
print(s1)
os.makedirs(s1)
os.listdir()
C:\Users\ps\Desktop\Blog\lixo
C:\Users\ps\Desktop\Blog\lixo\lixo1
Out[13]:
['cienciapolitica.txt', 'cp.txt', 'dep1.xlsx', 'lixo1']
As vezes deseja-se remover um diretório. Para isto pode ser usada a função
  • os.rmdir('caminho_do_dir_a_ser_removido')
Entretanto esta função só funciona se o diretório estiver vazio. Para esvaziar o diretório removendo todos seus arquivos pode-se usar código assim, desde que só hajam arquivos no diretório:
for f in os.listdir():
    os.unlink(f)
Um módulo muito útil é o submódulo os.path que contém funções para pegar nomes e extenções de arquivos, testar se objetos num diretório são arquivos ou se são diretórios e diversas outras utilidades.
Em nosso caso podemos usar a função os.path.isfile(f) para testar se o objeto f é um arquivo ou não. Nosso código acima fica assim:
# esvazia o diretório corrente (cuidado!)
for f in os.listdir():
    if os.path.isfile(f):
        os.unlink(f)
    else:
        os.rmdir(f)
Esta tarefa pode ser feita de modo mais simples usando outro módulo cheio de utilidades, o shutil:
import os, shutil
s = getcwd()
shutil.rmtree(s)
Isto deleta o diretório em s e tudo que ele contem, arquivos, subdiretórios, etc. Obviamente uma função poderosa que deve ser usada com cuidado.
Mais uma função útil do módulo os.path é a que devolve o tamanho de um arquivo:
In [14]:
os.path.getsize('cp.txt')
Out[14]:
818

Lendo e escrevendo conteúdo de arquivos

Agora vejamos como ler ou modificar o conteúdo de arquivos.
O processo tem três passos em sequência:
  1. Usar a função open() para obter um objeto File, que permite o acesso ao arquivo
  2. Usar o(s) método(s) read() (write()) do objeto File para ler ou escrever conteúdo do arquivo
  3. Fechar o arquivo usando o método close() de File

Abrindo arquivos com o comando open()

Vamos por enquanto discutir leitura ou escrita de arquivos texto.
O comando open() recebe como argumentos o caminho do arquivo e um caracter r ou w para indicar "aberto para leitura (r)" ou "aberto para escrita (w)" conforme se deseje ler ou escrever no arquivo respectivamente. Opcionalmente pode-se incluir um argumento nomeado encoding= seguido de simbolo da decodificação desejada. Como já dito antes, UTF-8 é uma das codificações modernas mais populares, pelo menos para arquivos em inglês e arquivos na internet em geral.
A execução deste comando devolve um objeto File que nada mais é que a representação do arquivo no ambiente de execução do Python. File esconde as complexidades da leitura de fato dos bits do arquivo no disco.
In [36]:
f = open('cp.txt', 'r',encoding='utf-8')
type(f)
Out[36]:
_io.TextIOWrapper

Lendo e escrevendo conteudo em arquivos texto

Uma vez criado um objeto File podemos invocar seus métodos para leitura de texto. Temos duas opções:
  • f.read() devolve o conteúdo inteiro do arquivo em um string.
  • f.readlines() devolve uma lista onde cada elemento é um string correspondente a uma linha do texto (uma linha termina com CR-LF)
In [37]:
txt = f.read()
print(txt)
A Ciência Política surgiu como disciplina e instituição em meados do século XIX, período em que avançou como "Ciência do Estado" principalmente na Alemanha, Itália e França. 
De maneira mais ampla, a Ciência Política pode ser entendida como a disciplina que se volta para o estudo de qualquer fenômeno ligado às estruturas políticas de maneira sistemática, sempre apoiado na observação empírica rigorosa e fundamentado em argumentos racionais.
 Nesse sentido, a palavra "ciência" é usada como ideia oposta à noção de "opinião", de forma que, como Noberto Bobbio* esclarece em seu Dicionário de Política, "ocupar-se cientificamente de política significa não se abandonar a opiniões e crenças do vulgo, não formular juízos com base em dados imprecisos, mas apoiar-se nas provas dos fatos."
 
Arquivos deixados abertos criam diversos problemas. Sempre feche os arquivos após usá-los:
In [38]:
f.close()
Vejamos a leitura de linhas do texto:
In [41]:
f = open('cp.txt', 'r',encoding='utf-8')
linhas = f.readlines()
print(linhas)
f.close()
['A Ciência Política surgiu como disciplina e instituição em meados do século XIX, período em que avançou como "Ciência do Estado" principalmente na Alemanha, Itália e França. \n', 'De maneira mais ampla, a Ciência Política pode ser entendida como a disciplina que se volta para o estudo de qualquer fenômeno ligado às estruturas políticas de maneira sistemática, sempre apoiado na observação empírica rigorosa e fundamentado em argumentos racionais.\n', ' Nesse sentido, a palavra "ciência" é usada como ideia oposta à noção de "opinião", de forma que, como Noberto Bobbio* esclarece em seu Dicionário de Política, "ocupar-se cientificamente de política significa não se abandonar a opiniões e crenças do vulgo, não formular juízos com base em dados imprecisos, mas apoiar-se nas provas dos fatos."\n', ' ']
Usando o comando with do Python, visto em aulas anteriores, não precisamos explicitamente fechar o arquivo. Ao terminar de executar o corpo do comando with este fecha o arquivo implicitamente:
In [42]:
with open('cp.txt', 'r',encoding='utf-8') as f:
    txt = f.read()
print(txt)
A Ciência Política surgiu como disciplina e instituição em meados do século XIX, período em que avançou como "Ciência do Estado" principalmente na Alemanha, Itália e França. 
De maneira mais ampla, a Ciência Política pode ser entendida como a disciplina que se volta para o estudo de qualquer fenômeno ligado às estruturas políticas de maneira sistemática, sempre apoiado na observação empírica rigorosa e fundamentado em argumentos racionais.
 Nesse sentido, a palavra "ciência" é usada como ideia oposta à noção de "opinião", de forma que, como Noberto Bobbio* esclarece em seu Dicionário de Política, "ocupar-se cientificamente de política significa não se abandonar a opiniões e crenças do vulgo, não formular juízos com base em dados imprecisos, mas apoiar-se nas provas dos fatos."
 

Organizando seus arquivos

Na prática gasta-se muita programação copiando arquivos e diretórios ou movendo arquivos e diretórios de um lugar para outro.
Um módulo cheio de funções úteis para tanto é o shutil. Vejamos algumas funções populares usadas no dia a dia.

copiando arquivos e diretórios

Pra copiar um arquivo para outro caminho use a função shutil.copy(caminho_velho,caminho_novo) Repare que podemos usar isto para renomear o arquivo velho em seu novo caminho.
In [43]:
import shutil
os.listdir()
Out[43]:
['cienciapolitica.txt', 'cp.txt', 'dep1.xlsx', 'lixo1']
In [44]:
shutil.copy('cienciapolitica.txt', r'lixo1\cipol.txt')
Out[44]:
'lixo1\\cipol.txt'
In [46]:
os.listdir('lixo1')
Out[46]:
['cipol.txt']
Para copiar diretórios usamos shutil.copytree(velho,novo). Por exemplo vamos copiar o diretório lixo1 para o diretório lixo aproveitando para renomear como temp
In [47]:
shutil.copytree('lixo1', 'temp')
Out[47]:
'temp'
In [48]:
os.listdir()
Out[48]:
['cienciapolitica.txt', 'cp.txt', 'dep1.xlsx', 'lixo1', 'temp']
In [49]:
os.listdir('temp')
Out[49]:
['cipol.txt']
Mover arquivos ou diretórios poderia ser feito em duas etapas:
  • copiar o arquivo para o destino
  • deletar o arquivo no diretório corrente
Entretanto usando shutil podemos fazer isto com uma só chamada de função: shutil.move(origem, destino)
In [51]:
shutil.move('temp\\cipol.txt', os.getcwd())
Out[51]:
'C:\\Users\\ps\\Desktop\\Blog\\lixo\\cipol.txt'
In [52]:
os.listdir()
Out[52]:
['cienciapolitica.txt', 'cipol.txt', 'cp.txt', 'dep1.xlsx', 'lixo1', 'temp']
In [53]:
os.listdir('temp')
Out[53]:
[]

No comments:

Post a Comment