给定一个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文件夹不应该存在,其内容应该在根目录。
答案 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及更高版本应该是安全的。