/ / Dekomprimiere den Zlib-String mit ByteArrays - Python, Flex, Actionscript-3, Komprimierung, Zlib

Dekomprimieren Sie die Zlib-Zeichenfolge in ByteArrays - python, flex, actionscript-3, compression, zlib

Ich habe eine in Adobe Flex entwickelte Webanwendung3 und Python 2.5 (bereitgestellt in Google App Engine). In Python wurde ein RESTful-Webdienst erstellt, dessen Ergebnisse derzeit in einem XML-Format vorliegen, das von Flex mithilfe des HttpService-Objekts gelesen wird.

Das Hauptziel ist nun, das XML so zu komprimierendass zwischen der send () - Methode von HttpService und den Ergebnisereignissen weniger Zeit liegt. Ich habe nach Python-Dokumenten gesucht und es geschafft, mit zlib.compress () das XML-Ergebnis zu komprimieren.

Dann habe ich den Ergebnistyp HttpService von "xml" auf "text" gesetzt und mit ByteArrays versucht, die Zeichenfolge wieder in XML zu dekomprimieren. Hier habe ich versagt. Ich mache so etwas:

var byteArray:ByteArray = new ByteArray();
byteArray.writeUTF( event.result.toString() );
byteArray.uncompress();
var xmlResult:XML = byteArray.readUTF();

Es löst eine Ausnahme bei byteArray.uncompress () aus und sagt, dass das byteArray nicht dekomprimiert werden kann. Auch wenn ich die Länge des byteArray nachverfolge, erhält es 0.

Ich kann nicht herausfinden, was ich falsch mache. Alle Hilfe wird geschätzt.

- Bearbeiten -

Der Code:

# compressing the xml result in Python
print zlib.compress(xmlResult)

# decompresisng it in AS3
var byteArray:ByteArray = new ByteArray();
byteArray.writeUTF( event.result.toString() );
byteArray.uncompress()

Ereignis ist vom Typ ResultEvent.

Der Fehler:

Fehler: Fehler # 2058: Beim Dekomprimieren der Daten ist ein Fehler aufgetreten.

Der Fehler kann daran liegen, dass der Wert von byteArray.bytesAvailable = 0, was bedeutet, dass das generierte Python-Rohbyte nicht richtig in byteArray geschrieben wurde.

- Sri

Antworten:

2 für die Antwort № 1

Was ist byteArray.writeUTF( event.result.toString() ); tun soll? Das Ergebnis von zlib.compress () ist weder Unicode noch "UTF" (bedeutungslos ohne eine Zahl danach !?); es ist binär, auch als rohe Bytes bekannt; Sie sollten es weder dekodieren noch kodieren oder eine andere Transformation darauf anwenden. Der Empfänger sollte die empfangenen Rohbytes sofort dekomprimieren, um die an zlib.compress () übergebenen Daten wiederherzustellen.

Aktualisieren Welche Unterlagen müssen Sie die Vorstellung unterstützen, dass byteArray.uncompress() erwartet ein wahres zlib Stream und nicht ein Luft ablassen stream (d. h. ein zlib stream nachdem du die ersten 2 Bytes und die letzten 4 abgeschnitten hast)?

Die Flex 3-Dokumentation von ByteArray gibt dieses Beispiel:

bytes.uncompress(CompressionAlgorithm.DEFLATE);

Wenn es einen Standard gibt, ist er nirgends offensichtlich, daher ist es eine sehr gute Idee, ihn zu verwenden

bytes.uncompress(CompressionAlgorithm.ZLIB);

um deutlich zu machen, was Sie vorhaben.

UND die docs sprechen über a writeUTFBytes Methode, nicht a writeUTF Methode. Sind Sie sicher, dass Sie den genauen Empfängercode in Ihrer Frage kopiert / eingefügt haben?

Update 2

Danke für die URL. Sieht so aus, als hätte ich die "Hilfe" bekommen, nicht die echten Dokumente: = (. Ein paar Punkte:

(1) Ja, es gibt eine explizite inflate() Methode. Dekomprimieren Sie DOES jedoch mit einem Algorithmus arg; Es kann sich entweder um CompressionAlgorithm.ZLIB (Standardeinstellung) oder CompressionAlgorithm.DEFLATE handeln. Interessanterweise ist Letzteres jedoch nur in Adobe Air und nicht in Flash Player verfügbar. Zumindest wissen wir, dass der Aufruf von uncompress () in Ordnung ist, und wir können auf das Problem zurückkommen, die unformatierten Bytes auf die Leitung und wieder in eine ByteArray-Instanz zu übertragen.

(2) Wichtiger ist, dass es beides gibt writeUTF (Schreibt eine utf-8-Zeichenfolge in den Bytestream. Die Länge der utf-8-Zeichenfolge in Bytes wird zuerst als 16-Bit-Ganzzahl geschrieben, gefolgt von den Bytes, die die Zeichen der Zeichenfolge darstellen.) Und writeUTFBytes (Schreibt eine utf-8-Zeichenfolge in den Byte-Stream. Ähnlich wie die writeUTF () -Methode, aber writeUTFBytes () stellt der Zeichenfolge kein 16-Bit-Wort voran.)

Unabhängig von den Vorteilen der Bereitstellung von UTF8-codierten Bytes (nil, IMHO) möchten Sie dort kein 2-Byte-Längen-Präfix haben. Die Verwendung von writeUTF () führt garantiert dazu, dass uncompress () kaputt geht.

Auf den Draht gebracht: Die Verwendung von Python-Druck für Binärdaten scheint keine gute Idee zu sein (es sei denn, sys.stdout wurde für die Ausführung im unformatierten Modus entwickelt, den Sie in Ihrem Code nicht gezeigt haben).

Ebenso ist es ziemlich unwahrscheinlich, dass event.result.toString () eine Zeichenfolge abruft (ähnlich einem Python-Unicode-Objekt, yes / no?) - womit und dann in utf-8 codiert.

Da ich bis heute nicht wusste, dass Flex existiert, kann ich Ihnen wirklich nicht effektiv helfen. Hier einige weitere Vorschläge zur Selbstversorgung für den Fall, dass niemand, der mehr über Flexibilität weiß, bald vorbeikommt:

(1) Führen Sie ein Debugging durch. Beginnen Sie mit einem minimalen XML-Dokument. Show repr(xml_doc). Show repr(zlib_compress_output). Verwenden Sie in (einer gekürzten) Version Ihres Flex-Skripts die Funktion / Methode, die der am nächsten kommt repr() dass Sie finden können, um zu zeigen: event.result, event.result.toString() und das Ergebnis von writeUTF*(). Stellen Sie sicher, dass Sie die Auswirkungen von allem verstehen, was nach zlib.compress () passieren kann. Das sorgfältige Lesen der Dokumente kann hilfreich sein.

(2) Sehen Sie sich an, wie Sie Rohbytes aus event.result erhalten können.

HTH, John