当我从使用Python zipfile
模块创建的ZIP文件中提取文件时,所有文件都不可写,只读等。如何使用Python的zipfile模块在ZIP文件中的文件上设置权限(属性)?
该文件正在Linux和Python 2.5.2下创建和提取。
尽我所知,我需要为每个文件设置ZipInfo.external_attr
属性,但这似乎没有记录在任何我能找到的地方,任何人都可以启发我吗?
当我从使用Python zipfile
模块创建的ZIP文件中提取文件时,所有文件都不可写,只读等。如何使用Python的zipfile模块在ZIP文件中的文件上设置权限(属性)?
该文件正在Linux和Python 2.5.2下创建和提取。
尽我所知,我需要为每个文件设置ZipInfo.external_attr
属性,但这似乎没有记录在任何我能找到的地方,任何人都可以启发我吗?
这似乎是工作(感谢埃文,把它在这里太行是在上下文中):
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
看看这个:Set permissions on a compressed file in python
我不能完全肯定,如果这就是你想要的,但它似乎是。
重点线似乎是:
zi.external_attr = 0777 << 16L
它看起来就像将权限设置为0777
那里。
谢谢,它确实有一些提示,但不是真的这样的答案,虽然... – Tom 2009-01-12 07:02:04
当你这样做时,它能正常工作吗?
zf = zipfile.ZipFile("something.zip")
for name in zf.namelist():
f = open(name, 'wb')
f.write(self.read(name))
f.close()
如果没有,我会建议扔在一个os.chmod
在for循环与0777的权限是这样的:
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)
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.
另外,在源InfoZIP的zip程序,从Debian's archives下载源文件的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。
较早的答案不适用于我(在OS X 10.12上)。我发现,以及可执行标志(八进制755),我还需要设置“常规文件”标志(八进制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的拉链让一切都在文件夹中Contents/MacOS/
可执行:https://gist.github.com/Draknek/3ce889860cea4f59838386a79cc11a85
如果在示例中定义了缓冲区,名称和字节,这将更具可读性。 – 2013-06-12 19:37:03
当然,添加了一些示例定义。 – Tom 2013-06-13 23:28:44
对于python 3,你可以写下这个`0o777 << 16` – 2015-08-28 02:30:59