Probleme mit zipfile unter windows 2000...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Irgendwie produiziert zipfile keine gültige ZIPs unter Windows 2000. Ich weiß nur nicht warum.

Erstmal ein Auszug aus dem Code:

Code: Alles auswählen

        buffer = StringIO.StringIO()
        z = zipfile.ZipFile(buffer, "w")

        for file_info in files:
            filename = file_info[0]
            abs_path = posixpath.join(self.request_path, filename)
            arcname = posixpath.join(artist, album, filename)

            z.write(abs_path, arcname)
        z.close()

        buffer.seek(0,2) # Am Ende der Daten springen
        buffer_len = buffer.tell() # Aktuelle Position
        buffer.seek(0) # An den Anfang springen

        filename = posixpath.split(self.request_path)[-1]

        self.request.headers['Content-Disposition'] = 'attachment; filename="%s.zip"' % filename
        self.request.headers['Content-Length'] = '%s' % buffer_len
        self.request.headers['Content-Transfer-Encoding'] = 'binary'
        self.request.headers['Content-Type'] = 'application/octet-stream;'# charset=utf-8'

        def send_data(buffer):
            while 1:
                data = buffer.read(2048)
                if not data:
                    return
                yield data
                time.sleep(0.1)

        self.request.send_response(send_data(buffer))
Unter Linux (Ubuntu) klappt alles richtig. Unter Windows 2000 sind die ZIP-Dateien unbrauchbar :( Anscheinend wäre der Header defekt. Mit einem Hex-Editor sieht alles "normal" aus...

Jemand einen Tipp für mich?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hab das ganze mal umgebaut, das man es lokal testen kann. Es werden dabei einfach alle Dateien im aktuellen Verzeichnis in test.zip eingepackt. Bei mir unter XP geht das einwandfrei:

Code: Alles auswählen

import os, posixpath, StringIO, zipfile, time

def create():
    buffer = StringIO.StringIO()
    z = zipfile.ZipFile(buffer, "w")

    artist = "test_verz_1"
    album = "test_verz_2"

    for item in os.listdir("."):
        if os.path.isfile(item):
            arcname = posixpath.join(artist, album, item)
            z.write(item, arcname)
    z.close()

    buffer.seek(0,2) # Am Ende der Daten springen
    buffer_len = buffer.tell() # Aktuelle Position
    buffer.seek(0) # An den Anfang springen

    def send_data(buffer):
        while 1:
            data = buffer.read(2048)
            if not data:
                return
            yield data
            time.sleep(0.000001)

    f = file("test.zip", "wb")
    for block in send_data(buffer):
        f.write(block)
    f.close()

create()

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Mach aus der Content-Type Zeile mal folgendes:

Code: Alles auswählen

self.request.headers['Content-Transfer-Encoding'] = '8bit'
self.request.headers['Content-Type'] = 'application/octet-stream'# ;charset=utf-8'
Bei Content-Transfer-Encoding ist 8bit eigentlich identisch zu binary (wobei ersteres gängiger ist, zumindest im Zusammenhang mit MIME), aber es so zu probieren kann ja mal nicht schaden. ;-)
--- Heiko.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben:Unter Linux (Ubuntu) klappt alles richtig. Unter Windows 2000 sind die ZIP-Dateien unbrauchbar :( Anscheinend wäre der Header defekt. Mit einem Hex-Editor sieht alles "normal" aus...
Hi Jens!

Das gleiche Problem hatte ich auch. Allerdings ging es mir dann so auf die Nerven, dass ich auf das Modul "tarfile" ausgewichen bin.

Ich glaube, dass der Unterschied ein Zeilenumbruch am Ende des Files war.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Guter Tipp. Neben tar könnte ich es auch mit bz2 probieren.

Hab keinen Bug bei http://sourceforge.net/tracker/?group_i ... tid=105470 gefunden. Ob es nun wirklich an der zlibn liegt?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich hab das Problem in die deutsche Maillingliste http://python.net/pipermail/python-de/2 ... 07591.html geschildert. Allerdings bisher ohne Resonanz.
Leider kann ich selber nicht testen, da ich kein Win2000 hab.

@gerold: Kannst du mehr zum Problem sagen?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben:@gerold: Kannst du mehr zum Problem sagen?
Hi Jens!

Tut mir leid, ist schon zu lange her.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

So, ich hab jetzt alles auf tarfile umgestellt und auch kein StringIO benutzt, dennoch sind die Archive defekt :evil:

EDIT: Mit 'Content-Transfer-Encoding' = '8bit' geht es auch nicht...
Zuletzt geändert von jens am Donnerstag 2. März 2006, 19:49, insgesamt 1-mal geändert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Python 47
User
Beiträge: 574
Registriert: Samstag 17. September 2005, 21:04

Hast du mal Modelnine´s Tipp ausprobiert?
mfg

Thomas :-)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

jens hat geschrieben:Bei mir unter XP geht das einwandfrei:

Code: Alles auswählen

import os, posixpath, StringIO, zipfile, time

def create():
    buffer = StringIO.StringIO()
    z = zipfile.ZipFile(buffer, "w")
    ...
Hi Jens!

Ich habe diesen Code bei mir ausprobiert. Er funktioniert einwandfrei. Und das, obwohl du die Funktion "buffer()" überschrieben hast.

Windows 2000 -- Alle Servicepacks und Updates die es gibt.
Python 2.4.1

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also ich hab nun mal auf beiden Systemen ein TarFile erzeugt und mit einem Hex-Editor verglichen... Beim 2000er sind im Datenstrom ein zusätzliche Zeichen drin:
...a8ed 9d0a 75c0 0036... <- funktioniertendes tar
...a8ed 9d0d 0a75 c000... <- defektes Win2000 tar

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hier wieder eine herraus gelöste Version:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os, posixpath, time
from tempfile import NamedTemporaryFile
from tarfile import TarFile

def create():
    temp = NamedTemporaryFile(prefix="PyDown_")
    tar = TarFile(mode="w", fileobj=temp)

    artist = "test_verz_1"
    album = "test_verz_2"

    for item in os.listdir("."):
        if os.path.isfile(item):
            arcname = posixpath.join(artist, album, item)
            tar.add(item, arcname)
    tar.close()

    temp.seek(0,2) # Am Ende der Daten springen
    temp_len = temp.tell() # Aktuelle Position
    temp.seek(0) # An den Anfang springen

    def send_data(temp):
        while 1:
            data = temp.read(2048)
            if not data:
                return
            yield data
            time.sleep(0.000001)

    f = file("test.tar", "wb")
    for block in send_data(temp):
        f.write(block)
    f.close()

create()

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

jens hat geschrieben:
...a8ed 9d0a 75c0 0036... <- funktioniertendes tar
...a8ed 9d0d 0a75 c000... <- defektes Win2000 tar
\x0d == \r
\x0a == \n :wink:

Damit wäre klar, dass da windows seine carrige returns reinhaut.
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also bin ein wenig weiter... Es liegt nicht an colubrid und nicht am zip/tar-File selber... Auch ist kein 2000 sondern doch ein XP im Spiel... Anscheinend liegt es irgendwie am Windows XAMPP...

Ich hab ein neues kleineres Testskript geschrieben:

Code: Alles auswählen

#!D:\python\python24\python.exe
# -*- coding: UTF-8 -*-

#~ print "Content-type: text/html; charset=utf-8\n"
#~ import cgitb;cgitb.enable()

import sys, os, posixpath, time, glob
from tempfile import NamedTemporaryFile
from tarfile import TarFile


temp = NamedTemporaryFile(prefix="PyDown_")

tar = TarFile(mode="w", fileobj=temp)

for item in glob.glob("*.mp3"):
    tar.add(item)

tar.close()

print "Content-Disposition: attachment; filename=test.tar"
#~ print 'Content-Transfer-Encoding: binary'
print "Content-Transfer-Encoding: 8bit"
print "Content-Type: application/octet-stream;\n"# charset=utf-8\n'

f = file("test.tar", "wb")
while 1:
    data = temp.read(2048)
    if not data:
        break
    f.write(data)
    sys.stdout.write(data)

f.close()

temp.close()
Die parallel erzeugte Datei ist in Ordnung... Die downgeloadete Datei ist defekt :(

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi Jens!

Dieser Code erzeugt identische Files beim Aufruf mit

Code: Alles auswählen

python skriptname.py > test2.tar

Code: Alles auswählen

#!D:\python\python24\python.exe
# -*- coding: UTF-8 -*-

#~ print "Content-type: text/html; charset=utf-8\n"
#~ import cgitb;cgitb.enable()

import sys, os, posixpath, time, glob
from tempfile import NamedTemporaryFile
from tarfile import TarFile

temp = NamedTemporaryFile(prefix="PyDown_")

tar = TarFile(mode="w", fileobj=temp)

for item in glob.glob("*.txt"):
    tar.add(item)

tar.close()

#print "Content-Disposition: attachment; filename=test.tar"

#~ print 'Content-Transfer-Encoding: binary'

#print "Content-Transfer-Encoding: 8bit"
#print "Content-Type: application/octet-stream;\n"# charset=utf-8\n'



# force input/output to binary
if sys.platform == "win32":
    import msvcrt
    msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)



f = file("test.tar", "wb")

temp.seek(0)

while 1:
    data = temp.read(2048)
    if not data:
        break
    f.write(data)
    sys.stdout.write(data)

f.close()

temp.close()
lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

gerold hat geschrieben:Dieser Code erzeugt identische Files beim Aufruf mit

Code: Alles auswählen

python skriptname.py > test2.tar
Hi Jens!

Wenn man die Kommentarzeichen vor den "print"-Anweisungen, die für das CGI notwendig sind, wieder entfernt, dann funktioniert es auch mit XAMPP unter Windows 2000.

Code: Alles auswählen

print "Content-Disposition: attachment; filename=test.tar"
print "Content-Transfer-Encoding: 8bit"
print "Content-Type: application/octet-stream;\n"

# force input/output to binary
if sys.platform == "win32":
    import msvcrt
    msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
[...]
temp.seek(0)
Ich habe dieses Skript soeben getestet.

Hier das gesamte Skript, genau so wie ich es getestet habe. Danach habe ich die Ergebnisse mit "cmp" vom Cygwin verglichen und zum Test mit WinZip geöffnet. Allerdings habe ich nur Textdateien komprimiert. Vielleicht versuche ich es später noch mit anderen Dateien, aber erst mal mache ich Schluß.

Code: Alles auswählen

#!C:\Python24\python.exe
# -*- coding: iso-8859-1 -*-

#~ print "Content-type: text/html; charset=utf-8\n"
#~ import cgitb;cgitb.enable()

import sys, os, posixpath, time, glob
from tempfile import NamedTemporaryFile
from tarfile import TarFile

temp = NamedTemporaryFile(prefix="PyDown_")

tar = TarFile(mode="w", fileobj=temp)

for item in glob.glob("*.txt"):
    tar.add(item)

tar.close()

print "Content-Disposition: attachment; filename=test.tar"

#~ print 'Content-Transfer-Encoding: binary'

print "Content-Transfer-Encoding: 8bit"
print "Content-Type: application/octet-stream;\n"# charset=utf-8\n'



# force input/output to binary
if sys.platform == "win32":
    import msvcrt
    msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)



f = file("test.tar", "wb")

temp.seek(0)

while 1:
    data = temp.read(2048)
    if not data:
        break
    f.write(data)
    sys.stdout.write(data)

f.close()

temp.close()
lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich dummie :oops: Ich hatte wahrscheinlich das .seek(0) vergessen, deswegen klappte es nicht mit dem Test-Skript :(

Auf jeden Fall scheint es nun zu klappen!!! Dank dir, für deine Geduld.

Ich Frage mich, warum man überhaupt explizit den stdout auf binär setzten muß?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

jens hat geschrieben:Ich Frage mich, warum man überhaupt explizit den stdout auf binär setzten muß?
Weil Windows sonst aus jedem '\n' ein '\r\n' macht.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Wie nett doch Windows ist :evil:

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten