() translation by (you can also view the original English article)
Se você já usa há algum tempo, é provável que já tenha visto arquivos com a extensão .zip. São arquivos especiais que podem guardar o conteúdo comprimido de vários outros arquivos, pastas e subpastas. Isso os torna bem úteis para transferências de arquivo via internet. Você sabia que podemos usar Python para comprimir ou extrair arquivos?
O tutorial mostrará o uso do módulo zipfile em Python para extrair e comprimir arquivos individuais ou vários de uma só vez.
Comprimindo Arquivos Individuais
Essa é fácil e requer pouco código. Começamos importando o módulo zipfile e então abrimos o objeto ZpFile em modo de escrita, especificando 'w' como segundo parâmetro. O primeiro parâmetro é o caminho do arquivo em si. Eis o código que precisamos:
1 |
import zipfile |
2 |
|
3 |
jungle_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\jungle.zip', 'w') |
4 |
jungle_zip.write('C:\\Stories\\Fantasy\\jungle.pdf', compress_type=zipfile.ZIP_DEFLATED) |
5 |
|
6 |
jungle_zip.close() |
Notemos que especificaremos o caminho dos arquivos no estilo Windows em todos os trechos de código. É preciso fazer as mudanças necessárias para Linux ou Mac.
Podemos especificar diferentes métodos de compressão para comprimir arquivos. Os novos métodos BZIP2
e LZMA
foram adicionadas à versão 3.3 do Python e há algumas ferramentas que não suportam esses dois métodos de compressão. Por isso, é mais seguro usar só o método DEFLATED
. Porém, deveríamos testar os outros métodos para ver a diferença do tamanho do arquivo comprimido.
Comprimindo Vários Arquivos
Esse é "mais complexo" por termos de iterar sobre os arquivos. O código abaixo deve comprimir todos os arquivos PDF em uma dada pasta:
1 |
import os |
2 |
import zipfile |
3 |
|
4 |
fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip', 'w') |
5 |
|
6 |
for folder, subfolders, files in os.walk('C:\\Stories\\Fantasy'): |
7 |
|
8 |
for file in files: |
9 |
if file.endswith('.pdf'): |
10 |
fantasy_zip.write(os.path.join(folder, file), os.path.relpath(os.path.join(folder,file), 'C:\\Stories\\Fantasy'), compress_type = zipfile.ZIP_DEFLATED) |
11 |
|
12 |
fantasy_zip.close() |
Dessa vez, importamos o módulo os
e usamos o método walk()
para iterar pelos arquivos e subpasta dentro da pasta original. Comprimimos apenas os arquivos PDF da pasta. Também podemos criar arquivos zip diferentes para cada formato, usando declarações if
.
Se não queremos preservar a estrutura do diretório, podemos unir todos os arquivos, usando a linha a seguir:
1 |
fantasy_zip.write(os.path.join(folder, file), file, compress_type = zipfile.ZIP_DEFLATED) |
O método write()
aceita três parâmetros. O primeiro é o nome do arquivo que queremos comprimir. O segundo é opcional e permite-nos especificar um nome diferente para o arquivo comprimido. Se nada for especificado, o nome original é usado.
Extraindo Todos Arquivos
Podemos usar o método extractall()
para extrair todos os arquivos e pastas de um arquivo zip no diretório atual. Também podemos passar o nome do diretório para extractall()
extrair os arquivos e pastas em um local específico. Se a pasta passada não exisitir, ela será criada. Eis o código para extrair arquivos:
1 |
import zipfile |
2 |
|
3 |
fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip') |
4 |
fantasy_zip.extractall('C:\\Library\\Stories\\Fantasy') |
5 |
|
6 |
fantasy_zip.close() |
Se quisermos extrair vüarios arquivos, devemos passar os nomes dos arquivos a extrair como uma lista.
Extraindo Arquivos Individuais
É parecido a extrair vários arquivos. A diferença é que precisamos passar o nome do arquivo primeiro e o caminho para colocá-los, depois. Também precisamos usar o método extract()
ao invés de extractall()
. Eis um código básico para extrair arquivos individuais.
1 |
import zipfile |
2 |
|
3 |
fantasy_zip = zipfile.ZipFile('C:\\Stories\\Fantasy\\archive.zip') |
4 |
fantasy_zip.extract('Fantasy Jungle.pdf', 'C:\\Stories\\Fantasy') |
5 |
|
6 |
fantasy_zip.close() |
Lendo Arquivos Zip
Consideremos o cenário onde precisamos ver se um arquivo zip contém um arquivo em específico. Até agora, nossa única opção era extrair todo o conteúdo do arquivo. De forma similar, talvez precisemos extrair arquivos maiores que certo tamanho. O módulo zipfile
permite-nos invetigar o conteúdo de um arquivo sem precisar extraí-lo.
Usando namelist()
do objeto ZipFile retornará uma lista de todos os membros de um arquivo, nomeadamente. Para obter informação de um arquivo específico do arquivo, podemos usar getinfo()
do objeto ZipFile. Isso nos dará acesso a informação específico do arquivo, como tamanho comprimido e normal ou seu último horário de modificação. Retornaremos a isso depois.
Chamar getinfo()
em cada um dos arquivos do zip pode ser bem trabalhose quando se tem vários arquivos a se processar. Nesse caso, podemos usar infolist()
para retornar uma lista contendo um objeto ZipInfo de cada membro do arquivo. A ordem desses objetos na lista é a mesma nos zipfiles.
Também podemos ler o conteúdo de um arquivo específico do arquivo, usando read(file)
, onde file
é o nome do arquivo que queremos ler. Para isso, o arquivo é preciso abrí-lo no modo leitura ou anexo.
Para obter o tamanho comprimido de um arquivo dentro do zip, podemos usar o atributo compress_size
. De forma similar, para saber o tamanho real, usamos o atributo file_size
.
O código abaixo usa as propriedades e métodos discutido para extrair apenas os arquivos com tamanho maior que 1MB.
1 |
import zipfile |
2 |
|
3 |
stories_zip = zipfile.ZipFile('C:\\Stories\\Funny\\archive.zip') |
4 |
|
5 |
for file in stories_zip.namelist(): |
6 |
if stories_zip.getinfo(file).file_size < 1024*1024: |
7 |
stories_zip.extract(file, 'C:\\Stories\\Short\\Funny') |
8 |
|
9 |
stories_zip.close() |
Para saber o horário e data de quando um arquivo do zip foi modificado pela útlima vez, usamos o atributo date_time
. Isso retornará uma tupla com seis valores. Os valores serão o ano, mês, dia do mês, horas, miutos e segundos, nessa ordem. O ano sempre será maior que 1980, e horas, minutos e segundos terão zero a esquerda.
1 |
import zipfile |
2 |
|
3 |
stories_zip = zipfile.ZipFile('C:\\Stories\\Funny\\archive.zip') |
4 |
|
5 |
thirsty_crow_info = stories_zip.getinfo('The Thirsty Crow.pdf') |
6 |
|
7 |
print(thirsty_crow_info.date_time) |
8 |
print(thirsty_crow_info.compress_size) |
9 |
print(thirsty_crow_info.file_size) |
10 |
|
11 |
stories_zip.close() |
A informação do tamanho do arquivo original e comprimido podem ajudar a decidir se vale comprimir ou não um arquivo. Garantimos que podem ser usada em outras situações também.
Pontos Finais
Como evidente no tutorial, usar o módulo zipfile
para comprimir arquivos, dá-nos muita flexibilidade. Podemos comprimir arquivos diferentes em um diretório em arquivos diferentes baseado em seus tipo, nome e tamanho. Também podemos decidir se queremos preservar a estrutura da pasta ou não. De forma similar, ao extrair arquivos, podemos fazê-lo onde quisermos e como quisermos, baseado no tamanho, etc.
Para sermos sinceros, achamos bem legar extrair e comprimir arquivos usando nosso próprio código. Esperamos que tenham curtido o tutorial e quaisquer dúvidas, deixe um comentário.