使用python的ZipFile lib解压缩会产生奇怪的结果

时间:2014-07-21 10:30:56

标签: python unzip

给定一个zip文件和python ZipFile库,我在解压缩时会出现一个奇怪的输出:位于归档根目录的文件被提取到一个以归档名称本身命名的子目录。 / p>

以下是我使用ZipFile库的方式:

#!/usr/bin/X11/python

import sys
import urllib
import zipfile
import os.path
import os
import tempfile

def unzip(source_filename, dest_dir):
    with zipfile.ZipFile(source_filename) as zf:
        for member in zf.infolist():
            # Path traversal defense copied from
            # http://hg.python.org/cpython/file/tip/Lib/http/server.py#l789
            words = member.filename.split('/')
            path = dest_dir
            for word in words[:-1]:
                drive, word = os.path.splitdrive(word)
                head, word = os.path.split(word)
                if word in (os.curdir, os.pardir, ''): continue
                path = os.path.join(path, word)
            zf.extract(member, path)

try:
    # Get the latest release
    print 'Downloading stack archive...'
    (vagrantstack, infoheaders) = urllib.urlretrieve ('https://github.com/jquery/globalize/archive/master.zip')

    # Unzip in the project folder
    print 'Unzipping...'
    unzip(vagrantstack, '.')

finally:
    urllib.urlcleanup()

这应该重现jquery / globalize存储库的确切结构,而是所有的根文件都放在子目录中......

有人可以在这里指出问题吗?

免责声明:解压缩功能本身不是我的,但对我来说似乎是正确的。

编辑:这是我得到的输出:

➜  test-py  ./test.py
Downloading stack archive...
Unzipping...
➜  test-py  ls -l
total 8
drwxr-xr-x 6 adrien adrien 4096 juil. 21 12:23 globalize-master
-rwxr-xr-x 1 adrien adrien 1032 juil. 21 12:23 test.py
➜  test-py  ls -l globalize-master
total 16
drwxr-xr-x 5 adrien adrien 4096 juil. 21 12:23 doc
drwxr-xr-x 2 adrien adrien 4096 juil. 21 12:23 globalize-master
drwxr-xr-x 8 adrien adrien 4096 juil. 21 12:23 src
drwxr-xr-x 6 adrien adrien 4096 juil. 21 12:23 test
➜  test-py  ls -l globalize-master/globalize-master
total 40
-rw-r--r-- 1 adrien adrien   354 juil. 21 12:23 bower.json
-rw-r--r-- 1 adrien adrien  1052 juil. 21 12:23 CONTRIBUTING.md
-rw-r--r-- 1 adrien adrien  6809 juil. 21 12:23 Gruntfile.js
-rw-r--r-- 1 adrien adrien  1826 juil. 21 12:23 LICENSE.txt
-rw-r--r-- 1 adrien adrien  2397 juil. 21 12:23 package.json
-rw-r--r-- 1 adrien adrien 14151 juil. 21 12:23 README.md
➜  test-py

globalize-master / globalize-master文件夹不应该存在,其内容应该在根目录。

2 个答案:

答案 0 :(得分:2)

您尝试下载的存档没有顶级文件。 存档包含一个名为globalize-master的目录,其中包含所有文件,因此您看到的行为是正确的。

如果您使用unzip提取内容,则会看到相同的行为:

$ls
globalize-master.zip
$unzip globalize-master.zip 
Archive:  globalize-master.zip
300a9dc6cb4a08eb847c8565ee01eae4cd9aa35c
   creating: globalize-master/
 extracting: globalize-master/.bowerrc  
  [...]
  inflating: globalize-master/test/util.js  
$ls -l
totale 116
drwxrwxr-x 5 username username   4096 lug 13 07:35 globalize-master
-rw-r--r-- 1 username username 113313 lug 21 12:44 globalize-master.zip

阅读消息来源很清楚unzip函数使用文件名所做的所有事情都是无用的,因为它已经由ZipFile.extract处理了。 unzip的正确版本是:

def unzip(source_filename, dest_dir):
    with zipfile.ZipFile(source_filename) as zf:
        for member in zf.infolist():
            zf.extract(member, dest_dir)

产生预期的输出。

请注意,这几乎与使用extractall方法相同:

def unzip(source_filename, dest_dir):
    with zipfile.ZipFile(source_filename) as zf:
        zf.extractall(dest_dir)

答案 1 :(得分:0)

unzip()中某处肯定存在问题。它在所有目录中创建globalize-master子目录,而不仅仅是根目录。

如果您信任zip文件来源,则可以使用zf.extractall(dest_dir)extractall()对于Python 2.7.4及更高版本应该是安全的。