Frage

Wenn ich Dateien aus einer ZIP-Datei mit dem Python erstellt extrahieren zipfile Modul, alle die Dateien sind nicht beschreibbar, nur lesen etc.

Die Datei unter Linux und Python erstellt und extrahiert wird 2.5.2.

Wie man am besten kann ich sagen, ich brauche für jede Datei die ZipInfo.external_attr Eigenschaft zu setzen, aber dies scheint nicht überall zu dokumentieren die ich finden konnte, kann mich jemand aufklären?

War es hilfreich?

Lösung

Das scheint (dank Evan, es hier setzen, so dass die Linie in Zusammenhang) zu arbeiten:

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()

Ich würde immer noch zu sehen, wie etwas, das diese ... Eine zusätzliche Ressource dokumentiert fand ich eine Notiz auf das ZIP-Dateiformat war: http://www.pkware.com/documents/casestudies/APPNOTE.TXT

Andere Tipps

Dieser Link hat mehr Informationen als alles andere, was ich waren Lage im Netz zu finden. Auch die Zip-Quelle hat nichts. Kopieren des entsprechenden Abschnitts für die Nachwelt. Dieser Patch ist wirklich nicht über dieses Format dokumentiert, das geht nur um zu zeigen, wie erbärmlich (liest nicht vorhanden) die aktuelle Dokumentation ist.

# 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, '')

Auch diesem Link hat die folgenden. Hier wird das niederwertige Byte vermutlich bedeutet, den äußersten rechten (niedrigste) Byte des vier Bytes. Also dieses ist für MS-DOS und kann vermutlich als sonst Null gelassen werden.

  

externe Datei-Attribut: (4 Byte)

      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.

Auch Unix / unix.c in den Quellen die Quelle für InfoZIP der Zip-Programm, heruntergeladene Datei von Debian Archive hat die folgenden in den Kommentaren.

  /* 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.
   */

Also zusammen all dies nehmen, es sieht aus wie nur die zweithöchste Byte tatsächlich verwendet wird, zumindest für Unix.

EDIT: ich über den Unix Aspekt dabei auf Unix.SX gefragt, in der Frage "

Look at this: Festlegen von Berechtigungen auf einer komprimierten Datei in Python

Ich bin nicht ganz sicher, ob das, was Sie wollen, aber es scheint zu sein.

Der Schlüssel Linie scheint zu sein:

zi.external_attr = 0777 << 16L

Es sieht aus wie es die Berechtigungen setzt dort 0777.

Die früheren Antworten nicht für mich arbeiten (auf OS X 10.12). Ich fand, dass auch die ausführbaren Flags (Oktal 755), ich brauche auch die „reguläre Datei“ Flag (Oktal 100000) zu setzen. Ich fand das hier erwähnt: https://unix.stackexchange.com/questions/ 14705 / the-zip-Format-external-Datei-Attribut

Ein komplettes Beispiel:

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()

Ein vollständiges Beispiel für meine spezifische usecase, eine Zip eines .app zu schaffen, so dass alles, was in dem Ordner Contents/MacOS/ ausführbar ist: https://gist.github.com/Draknek/3ce889860cea4f59838386a79cc11a85

Sie können die ZipFile Klasse erweitern die Standard-Dateiberechtigungen zu ändern:

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)

In diesem Beispiel wird die Standard-Dateiberechtigungen 664 und hält 775 für Verzeichnisse.

Related Code:

Wenn Sie es so tun, es ist in Ordnung funktioniert?

zf = zipfile.ZipFile("something.zip")
for name in zf.namelist():
    f = open(name, 'wb')
    f.write(self.read(name))
    f.close()

Wenn nicht, würde ich vorschlagen, in einer os.chmod in der for-Schleife mit 0777 Berechtigungen wie diese werfen:

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)

Schauen Sie auch auf das, was zipfile Moduls Python tut:

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
    ...

`` `

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top