当我从使用Python zipfile
模块创建的ZIP文件中提取文件时,所有文件都不可写,只读等。
正在Linux和Python 2.5.2下创建和提取该文件。
我可以告诉我,我需要为每个文件设置ZipInfo.external_attr
属性,但这似乎没有记录在任何我能找到的地方,有人可以启发我吗?
答案 0 :(得分:41)
这似乎有效(感谢Evan,把它放在这里,所以线条在上下文中):
buffer = "path/filename.zip" # zip filename to write (or file-like object)
name = "folder/data.txt" # name of file inside zip
bytes = "blah blah blah" # contents of file inside zip
zip = zipfile.ZipFile(buffer, "w", zipfile.ZIP_DEFLATED)
info = zipfile.ZipInfo(name)
info.external_attr = 0777 << 16L # give full access to included file
zip.writestr(info, bytes)
zip.close()
我仍然希望看到记录此内容的内容...我发现的其他资源是有关Zip文件格式的说明:http://www.pkware.com/documents/casestudies/APPNOTE.TXT
答案 1 :(得分:24)
This link提供的信息比我在网上找到的任何其他内容都多。即使是拉链源也没有任何东西。复制相关部分以供后代使用。这个补丁实际上并不是关于记录这种格式的,这只是为了说明当前文档是多么可悲(读取不存在)。
# 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, '')
此外,this link还有以下内容。 这里低位字节可能意味着四个字节中最右边(最低)的字节。所以这个是 对于MS-DOS,可能会被假设为零。
外部文件属性:(4个字节)
The mapping of the external attributes is host-system dependent (see 'version made by'). For MS-DOS, the low order byte is the MS-DOS directory attribute byte. If input came from standard input, this field is set to zero.
此外,从Debian's archives下载的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.
*/
所以把所有这些放在一起,看起来实际上只使用了第二高的字节,至少对于Unix来说。
编辑:我在Unix.SX的问题“The zip format's external file attribute”中询问了Unix的这方面。看起来我有些不对劲。具体来说,前两个字节都用于Unix。答案 2 :(得分:13)
看看这个:Set permissions on a compressed file in python
我不完全确定这是不是你想要的,但似乎是。
关键线似乎是:
zi.external_attr = 0777 << 16L
看起来它将权限设置为0777
。
答案 3 :(得分:7)
之前的答案对我不起作用(在OS X 10.12上)。我发现除了可执行标志(八进制755)之外,我还需要设置&#34;常规文件&#34;旗帜(八进制100000)。我在这里提到了这一点:https://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute
一个完整的例子:
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()
我的特定用例的完整示例,创建.app的zip,以便文件夹Contents/MacOS/
中的所有内容都是可执行的:https://gist.github.com/Draknek/3ce889860cea4f59838386a79cc11a85
答案 4 :(得分:2)
您可以扩展ConcreteClass
MyInterface<java.lang.String, java.lang.Integer>
class java.lang.String
class java.lang.Integer
-------
GenericClass
MyInterface<K, V>
K
V
类以更改默认文件权限:
if ( can_continue )..
此示例将默认文件权限更改为ZipFile
,并保留from zipfile import ZipFile, ZipInfo
import time
class PermissiveZipFile(ZipFile):
def writestr(self, zinfo_or_arcname, data, compress_type=None):
if not isinstance(zinfo_or_arcname, ZipInfo):
zinfo = ZipInfo(filename=zinfo_or_arcname,
date_time=time.localtime(time.time())[:6])
zinfo.compress_type = self.compression
if zinfo.filename[-1] == '/':
zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x
zinfo.external_attr |= 0x10 # MS-DOS directory flag
else:
zinfo.external_attr = 0o664 << 16 # ?rw-rw-r--
else:
zinfo = zinfo_or_arcname
super(PermissiveZipFile, self).writestr(zinfo, data, compress_type)
用于目录。
相关代码:
答案 5 :(得分:1)
要使用 Python 的 zipfile 模块对 ZIP 文件中的文件设置权限(Unix 属性),请将属性作为 ZipInfo 的 external_attr 的 16-31 位传递。
Python zipfile 模块接受 Unix 中的 ASi 额外块的 16 位“模式”字段(存储来自 struct stat 的 st_mode 字段,包含用户/组/其他权限、setuid/setgid 和符号链接信息等)上面提到的 external_attr 位。
您也可以导入 Python 的“stat”模块来获取模式常量定义。
您也可以在 create_system 中设置 3 以指定创建 ZIP 存档的操作系统:3 = Unix; 0 = 视窗。
这是一个例子:
#!/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')
答案 6 :(得分:0)
当你这样做的时候,它能正常工作吗?
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)
答案 7 :(得分:0)
还要看看Python's zipfile module的作用:
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
...
```