Как распаковать файл с помощью Python 2.4?

Мне трудно понять, как распаковать zip-файл с 2.4. extract() не входит в 2.4. Я ограничен использованием 2.4.4 на своем сервере.

Может кто-нибудь привести простой пример кода?


person Tapefreak    schedule 18.10.2011    source источник
comment
вы можете использовать оператор обратной галочки или каким-либо другим способом выполнить системную функцию и разархивировать файл   -  person user973254    schedule 18.10.2011
comment
что вы хотите сделать с обратной галочкой? о.О   -  person naeg    schedule 18.10.2011
comment
Если вы нашли этот вопрос, но используете более новую версию Python, сделайте следующее: zfile = zipfile.ZipFile(file_to_extract) zfile.extractall(target_dir)   -  person Fabian    schedule 18.06.2014
comment
@Fabian: Вы можете пропустить переменную zFile и просто иметь zipfile.ZipFile(file_to_extract).extractall(target_dir) - это страдает от той же проблемы, что и ваш код, а именно, что вы не close() ZipFile впоследствии, что может привести к некоторым проблемам с ОС (IE, вы выиграли не сможет удалить файл, потому что он будет отображаться как используемый Python.)   -  person ArtOfWarfare    schedule 27.01.2015


Ответы (5)


Вы должны использовать namelist() и extract(). Пример рассмотрения каталогов

import zipfile
import os.path
import os
zfile = zipfile.ZipFile("test.zip")
for name in zfile.namelist():
  (dirname, filename) = os.path.split(name)
  print "Decompressing " + filename + " on " + dirname
  if not os.path.exists(dirname):
    os.makedirs(dirname)
  zfile.extract(name, dirname)
person Vinko Vrsalovic    schedule 18.10.2011
comment
В итоге скопировал этот и заметил одну мелочь. По крайней мере, если вы заархивируете свой файл с помощью опции zip-файла win7 sendTo, и ваш zip-файл содержит вложенные папки, вам нужно изменить os.mkdir(имя_каталога) -> os.makedirs(имя_каталога). В противном случае вы можете получить исключения (Нет такого файла или каталога), так как zip-файл содержит только конечные папки. - person fastfox; 25.07.2013
comment
Что, если name — это каталог (не обычный файл)? Я наткнулся на этот случай. - person Nawaz; 08.08.2013
comment
Это решение не будет работать без дальнейших модификаций. Две проблемы: - использование fd.write не в цикле (поэтому мы не можем записать весь файл, если он большой). Использование zfile.extract(имя, конкретный_каталог) кажется более подходящим — использование os.mkdir не будет создавать подкаталоги. os.makedirs(concrete_dir) выглядит лучше - person Dmitriusan; 06.02.2014
comment
Вместо этого используйте zfile.extract(name, '.') в последней строке, чтобы сохранить заархивированную структуру папок. - person hurturk; 09.07.2014
comment
@VinkoVrsalovic Как сохранить извлеченные файлы? - person NumenorForLife; 28.04.2015

Есть некоторая проблема с ответом Винко (по крайней мере, когда я его запускаю). Я получил:

IOError: [Errno 13] Permission denied: '01org-webapps-countingbeads-422c4e1/'

Вот как это решить:

# unzip a file
def unzip(path):
    zfile = zipfile.ZipFile(path)
    for name in zfile.namelist():
        (dirname, filename) = os.path.split(name)
        if filename == '':
            # directory
            if not os.path.exists(dirname):
                os.mkdir(dirname)
        else:
            # file
            fd = open(name, 'w')
            fd.write(zfile.read(name))
            fd.close()
    zfile.close()
person Ovilia    schedule 30.01.2013
comment
Разве это не должно быть fd = open(name, 'wb') в случае, если некоторые из заархивированных файлов являются изображениями или иными двоичными файлами? - person Sled; 23.04.2013

Изменение ответа Овилии, чтобы вы также могли указать каталог назначения:

def unzip(zipFilePath, destDir):
    zfile = zipfile.ZipFile(zipFilePath)
    for name in zfile.namelist():
        (dirName, fileName) = os.path.split(name)
        if fileName == '':
            # directory
            newDir = destDir + '/' + dirName
            if not os.path.exists(newDir):
                os.mkdir(newDir)
        else:
            # file
            fd = open(destDir + '/' + name, 'wb')
            fd.write(zfile.read(name))
            fd.close()
    zfile.close()
person Sled    schedule 23.04.2013

Не полностью проверено, но все должно быть в порядке:

import os
from zipfile import ZipFile, ZipInfo

class ZipCompat(ZipFile):
    def __init__(self, *args, **kwargs):
        ZipFile.__init__(self, *args, **kwargs)

    def extract(self, member, path=None, pwd=None):
        if not isinstance(member, ZipInfo):
            member = self.getinfo(member)
        if path is None:
            path = os.getcwd()
        return self._extract_member(member, path)

    def extractall(self, path=None, members=None, pwd=None):
        if members is None:
            members = self.namelist()
        for zipinfo in members:
            self.extract(zipinfo, path)

    def _extract_member(self, member, targetpath):
        if (targetpath[-1:] in (os.path.sep, os.path.altsep)
            and len(os.path.splitdrive(targetpath)[1]) > 1):
            targetpath = targetpath[:-1]
        if member.filename[0] == '/':
            targetpath = os.path.join(targetpath, member.filename[1:])
        else:
            targetpath = os.path.join(targetpath, member.filename)
        targetpath = os.path.normpath(targetpath)
        upperdirs = os.path.dirname(targetpath)
        if upperdirs and not os.path.exists(upperdirs):
            os.makedirs(upperdirs)
        if member.filename[-1] == '/':
            if not os.path.isdir(targetpath):
                os.mkdir(targetpath)
            return targetpath
        target = file(targetpath, "wb")
        try:
            target.write(self.read(member.filename))
        finally:
            target.close()
        return targetpath
person ekhumoro    schedule 18.10.2011

Я тестирую в Python 2.7.3rc2, и ZipFile.namelist() не возвращает запись только с именем подкаталога для создания подкаталога, а только список имен файлов с подкаталогом, как показано ниже:

['20130923104558/control.json', '20130923104558/test.csv']

Таким образом, проверка

if fileName == '':

вообще не оценивается как True.

Поэтому я изменил код, чтобы проверить, существует ли dirName внутри destDir, и создать dirName, если он не существует. Файл извлекается, только если часть fileName не пуста. Таким образом, это должно учитывать условие, при котором имя каталога может отображаться в ZipFile.namelist().

def unzip(zipFilePath, destDir):
    zfile = zipfile.ZipFile(zipFilePath)
    for name in zfile.namelist():
        (dirName, fileName) = os.path.split(name)
        # Check if the directory exisits
        newDir = destDir + '/' + dirName
        if not os.path.exists(newDir):
            os.mkdir(newDir)
        if not fileName == '':
            # file
            fd = open(destDir + '/' + name, 'wb')
            fd.write(zfile.read(name))
            fd.close()
    zfile.close()
person Rajkumar S    schedule 23.09.2013
comment
Это не ответ, если вы используете python 2.7, см. мой комментарий к вопросу. - person Fabian; 18.06.2014