如何使用Python';s zipfile模块?

如何使用Python';s zipfile模块?,python,attributes,zip,file-permissions,zipfile,Python,Attributes,Zip,File Permissions,Zipfile,当我从使用Python模块创建的ZIP文件中提取文件时,所有文件都不可写、只读等 该文件是在Linux和Python 2.5.2下创建和提取的 据我所知,我需要为每个文件设置ZipInfo.external\u attr属性,但这似乎在我能找到的任何地方都没有记录,有人能告诉我吗?看看这个: 我不完全确定这是否是你想要的,但似乎是 关键的一行似乎是: zi.external_attr = 0777 << 16L zi.external\u attr=0777这似乎是可行的(谢谢Ev

当我从使用Python模块创建的ZIP文件中提取文件时,所有文件都不可写、只读等

该文件是在Linux和Python 2.5.2下创建和提取的

据我所知,我需要为每个文件设置
ZipInfo.external\u attr
属性,但这似乎在我能找到的任何地方都没有记录,有人能告诉我吗?

看看这个:

我不完全确定这是否是你想要的,但似乎是

关键的一行似乎是:

zi.external_attr = 0777 << 16L
zi.external\u attr=0777这似乎是可行的(谢谢Evan,把它放在这里,这样就可以把这一行放在上下文中了):

buffer=“path/filename.zip”#要写入的压缩文件名(或类似文件的对象)
name=“folder/data.txt”#zip中的文件名
bytes=“blah blah blah”#zip中的文件内容
zip=zipfile.zipfile(缓冲区“w”,zipfile.zip_已放气)
info=zipfile.ZipInfo(名称)

info.external_attr=0777当你这样做时,它工作正常吗

zf = zipfile.ZipFile("something.zip")
for name in zf.namelist():
    f = open(name, 'wb')
    f.write(self.read(name))
    f.close()
如果没有,我建议在for循环中加入一个具有0777权限的
os.chmod
,如下所示:

zf = zipfile.ZipFile("something.zip")
for name in zf.namelist():
    f = open(name, 'wb')
    f.write(self.read(name))
    f.close()
    os.chmod(name, 0777)
比我在网上能找到的任何东西都要多。即使是zip源代码也没有任何内容。为后代复制相关章节。这个补丁实际上并不是关于记录这种格式,它只是用来显示当前文档是多么可怜(阅读不存在)

# external_attr is 4 bytes in size. The high order two
# bytes represent UNIX permission and file type bits,
# while the low order two contain MS-DOS FAT file
# attributes, most notably bit 4 marking directories.
if node.isfile:
    zipinfo.compress_type = ZIP_DEFLATED
    zipinfo.external_attr = 0644 << 16L # permissions -r-wr--r--
    data = node.get_content().read()
    properties = node.get_properties()
    if 'svn:special' in properties and \
           data.startswith('link '):
        data = data[5:]
        zipinfo.external_attr |= 0120000 << 16L # symlink file type
        zipinfo.compress_type = ZIP_STORED
    if 'svn:executable' in properties:
        zipinfo.external_attr |= 0755 << 16L # -rwxr-xr-x
    zipfile.writestr(zipinfo, data)
elif node.isdir and path:
    if not zipinfo.filename.endswith('/'):
        zipinfo.filename += '/'
    zipinfo.compress_type = ZIP_STORED
    zipinfo.external_attr = 040755 << 16L # permissions drwxr-xr-x
    zipinfo.external_attr |= 0x10 # MS-DOS directory flag
    zipfile.writestr(zipinfo, '')
此外,InfoZIP的zip程序源文件中的源文件unix/unix.c(从下载)中有以下注释

  /* lower-middle external-attribute byte (unused until now):
   *   high bit        => (have GMT mod/acc times) >>> NO LONGER USED! <<<
   *   second-high bit => have Unix UID/GID info
   * NOTE: The high bit was NEVER used in any official Info-ZIP release,
   *       but its future use should be avoided (if possible), since it
   *       was used as "GMT mod/acc times local extra field" flags in Zip beta
   *       versions 2.0j up to 2.0v, for about 1.5 years.
   */
/*中下部外部属性字节(目前未使用):

*高位=>(有GMT mod/acc时间)>>>>不再使用 先前的答案对我来说并不适用(在OSX10.12上)。我发现,除了可执行标志(octal 755),我还需要设置“常规文件”标志(octal 100000)。我发现这里提到了:

一个完整的例子:

zipname = "test.zip"
filename = "test-executable"

zip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)

f = open(filename, 'r')
bytes = f.read()
f.close()

info = zipfile.ZipInfo(filename)
info.date_time = time.localtime()
info.external_attr = 0100755 << 16L

zip.writestr(info, bytes, zipfile.ZIP_DEFLATED)

zip.close()
zipname=“test.zip”
filename=“测试可执行文件”
zip=zipfile.zipfile(zipname,'w',zipfile.zip_已缩小)
f=打开(文件名“r”)
字节=f.read()
f、 关闭()
info=zipfile.ZipInfo(文件名)
info.date\u time=time.localtime()
info.external_attr=0100755还可以看看什么是:

def write(self,filename,arcname=None,compress_type=None):
...
st=os.stat(文件名)
...
zinfo=ZipInfo(弧名、日期和时间)

zinfo.external_attr=(st[0]&0xFFFF)您可以扩展
ZipFile
类来更改默认文件权限:

从zipfile导入zipfile,ZipInfo
导入时间
类许可ZipFile(ZipFile):
def writestr(self、zinfo_或_arcname、data、compress_type=None):
如果不存在(zinfo_或arcname,ZipInfo):
zinfo=ZipInfo(文件名=zinfo_或_arcname,
date\u time=time.localtime(time.time())[:6])
zinfo.compress_type=自压缩
如果zinfo.filename[-1]='/':
zinfo.external_attr=0o40775要使用Python的zipfile模块对ZIP文件中的文件设置权限(Unix属性),请将属性作为ZipInfo的外部_attr的第16-31位传递

Python zipfile模块接受上述外部属性位中Unix ASi额外块的16位“Mode”字段(该字段存储struct stat中的st_Mode字段,包含用户/组/其他权限、setuid/setgid和符号链接信息等)

您还可以导入Python的“stat”模块以获得模式常量定义

您还可以在create_system中设置3,以指定创建ZIP存档的操作系统:3=Unix;0=Windows

以下是一个例子:

#!/usr/bin/python

import stat
import zipfile

def create_zip_with_symlink(output_zip_filename, link_source, link_target):
    zipInfo  = zipfile.ZipInfo(link_source)
    zipInfo.create_system = 3 
    unix_st_mode = stat.S_IFLNK | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH
    zipInfo.external_attr = unix_st_mode << 16 
    zipOut = zipfile.ZipFile(output_zip_filename, 'w', compression=zipfile.ZIP_DEFLATED)
    zipOut.writestr(zipInfo, link_target)
    zipOut.close()

create_zip_with_symlink('cpuinfo.zip', 'cpuinfo.txt', '/proc/cpuinfo')
#/usr/bin/python
进口统计
进口拉链
def创建带有符号链接的链接(输出文件名、链接源、链接目标):
zipInfo=zipfile.zipInfo(链接\源)
zipInfo.create_system=3
unix|u st|u mode=stat.S|IFLNK | stat.S|u irsr | stat.S|uixusr | stat.S|uiwgrp | stat.S|uixgrp | stat S|uiroth | stat S| IWOTH | stat S| uixoth | stat

zipInfo.external_attr=unix_st_mode我没有使用Python来提取zip,zip是由Web服务器生成的,并使用用户机器上的某些东西来提取。在我的例子中是gnome归档管理器程序。如果在示例中定义了缓冲区、名称和字节,则可读性会更高。当然,添加了一些示例定义。对于python 3,您还需要编写此
0o777:编写时,此代码会将归档中写入的文件标记为1980年最后修改的文件;ZipInfo构造函数将上次修改的日期作为另一个构造函数。有关更正确的解决方案,请参阅更新的答案。如果使用stat模块中的常量(例如stat.S_iflink),示例中的一些常量将更清晰。在仔细研究这一点时,我发现@Epu技术上也不能保证s_iFlk等于0120000——正如我提到的,“Unix值与传统Unix实现上的值相同”,并提供了一个例子,但POSIX不能保证精确的数值(S_iFlk实际上也不保证作为常量存在),但0120000在zip上下文中始终表示符号链接,因为它是一种跨平台格式。
zipname = "test.zip"
filename = "test-executable"

zip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED)

f = open(filename, 'r')
bytes = f.read()
f.close()

info = zipfile.ZipInfo(filename)
info.date_time = time.localtime()
info.external_attr = 0100755 << 16L

zip.writestr(info, bytes, zipfile.ZIP_DEFLATED)

zip.close()
def write(self, filename, arcname=None, compress_type=None):
    ...
    st = os.stat(filename)
    ...
    zinfo = ZipInfo(arcname, date_time)
    zinfo.external_attr = (st[0] & 0xFFFF) << 16L      # Unix attributes
    ...
#!/usr/bin/python

import stat
import zipfile

def create_zip_with_symlink(output_zip_filename, link_source, link_target):
    zipInfo  = zipfile.ZipInfo(link_source)
    zipInfo.create_system = 3 
    unix_st_mode = stat.S_IFLNK | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH
    zipInfo.external_attr = unix_st_mode << 16 
    zipOut = zipfile.ZipFile(output_zip_filename, 'w', compression=zipfile.ZIP_DEFLATED)
    zipOut.writestr(zipInfo, link_target)
    zipOut.close()

create_zip_with_symlink('cpuinfo.zip', 'cpuinfo.txt', '/proc/cpuinfo')