使用 ByteArrays 解压缩 Zlib 字符串
我有一个使用 Adobe Flex 3 和 Python 2.5 开发的 Web 应用程序(部署在 Google App Engine 上)。已使用 Python 创建了 RESTful Web 服务,其结果当前采用 XML 格式,Flex 使用 HttpService 对象读取该格式。
现在的主要目标是压缩 XML,以便缩短 HttpService send() 方法和结果事件之间的时间。我查阅了 Python 文档并设法使用 zlib.compress() 来压缩 XML 结果。
然后,我将 HttpService 结果类型从“xml”设置为“text”,并尝试使用 ByteArrays 将字符串解压缩回 XML。这就是我失败的地方。我正在做这样的事情:
var byteArray:ByteArray = new ByteArray();
byteArray.writeUTF( event.result.toString() );
byteArray.uncompress();
var xmlResult:XML = byteArray.readUTF();
它在 byteArray.uncompress() 处抛出异常,并表示无法解压缩 byteArray。另外,当我跟踪 byteArray 的长度时,它得到 0。
无法弄清楚我做错了什么。感谢所有帮助。
-- 编辑 --
代码:
# 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()
事件的类型为 ResultEvent。
错误:
错误:错误#2058:解压缩数据时出错。
该错误可能是因为 byteArray.bytesAvailable = 0 的值,这意味着 python 生成的原始字节尚未正确写入 byteArray..
-- Sri
I have a web application developed in Adobe Flex 3 and Python 2.5 (deployed on Google App Engine). A RESTful web service has been created in Python and its results are currently in an XML format which is being read by Flex using the HttpService object.
Now the main objective is to compress the XML so that there is as less a time between the HttpService send() method and result events. I looked up Python docs and managed to use zlib.compress() to compress the XML result.
Then I set the HttpService result type from "xml" to "text" and tried using ByteArrays to uncompress the string back to XML. Here's where I failed. I am doing something like this:
var byteArray:ByteArray = new ByteArray();
byteArray.writeUTF( event.result.toString() );
byteArray.uncompress();
var xmlResult:XML = byteArray.readUTF();
Its throwing an exception at byteArray.uncompress() and says unable to uncompress the byteArray. Also when I trace the length of the byteArray it gets 0.
Unable to figure out what I'm doing wrong. All help is appreciated.
-- Edit --
The 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()
Event is of type ResultEvent.
The error:
Error: Error #2058: There was an error decompressing the data.
The error could be because the value of byteArray.bytesAvailable = 0 which means the raw bytes python generated hasn't been written into byteArray properly..
-- Sri
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
byteArray.writeUTF( event.result.toString() ); 应该做什么? zlib.compress() 的结果既不是 unicode 也不是“UTF”(后面没有数字就没有意义!?);它是二进制的,也称为原始字节;您不应对其进行解码或编码,也不应对其应用任何其他转换。接收方应立即解压缩其接收到的原始字节,以恢复传递给 zlib.compress() 的数据。
更新 您需要什么文档来支持
byteArray.uncompress()
期望真正的 zlib 流而不是 deflate 的概念 流(即截取前 2 个字节和后 4 个字节后的 zlib 流)?ByteArray 的 Flex 3 文档给出了这个例如:
bytes.uncompress(CompressionAlgorithm.DEFLATE);
但没有说明默认值(如果有)是什么。如果有默认值,则不会在任何明显的地方进行记录,因此最好使用
bytes.uncompress(CompressionAlgorithm.ZLIB);
来明确您的意图。
并且文档讨论的是 writeUTFBytes 方法,而不是 writeUTF 方法。您确定在问题中复制/粘贴了确切的接收者代码吗?
更新 2
感谢您提供 URL。看起来我掌握了“帮助”,而不是真正的文档:=(。有几点:
(1) 是的,有一个显式的
inflate()
方法。但是 uncompress 确实有一个算法 arg;它可以是 CompressionAlgorithm.ZLIB (默认)或 CompressionAlgorithm.DEFLATE ...但有趣的是,后者仅在 Adobe Air 中可用,在 Flash Player 中不可用 至少我们知道 uncompress() 调用似乎正常,并且我们可以回到将原始字节传输到 ByteArray 实例中的问题(2) 更重要的是,还有
writeUTF
(写入一个)。将 UTF-8 字符串写入字节流 首先写入 UTF-8 字符串的长度(以字节为单位)(作为 16 位整数),然后写入表示字符串字符的字节)和 writeUTFBytes< /code> (将 UTF-8 字符串写入字节流。与 writeUTF() 方法类似,但 writeUTFBytes() 不会使用 16 位长度的字作为字符串前缀)。 UTF8 编码的字节(nil,恕我直言),您不需要 2 字节长度的前缀; 使用 writeUTF() 肯定会导致 uncompress() 失败。
将其连接到网络上:在二进制数据上使用 Python print 似乎不是一个好主意(除非 sys.stdout 已经被贵族以原始模式运行,而您没有在代码中显示)。
同样,使用 event.result.toString() 获取一个字符串(类似于 Python unicode 对象,是/否?)——用什么然后将其编码为 UTF-8 似乎不太可能工作。
鉴于我直到今天才知道 Flex 的存在,我真的无法有效地帮助你。这里有一些关于自给自足的进一步建议,以防很快没有人知道更多的 Flex:
(1)进行一些调试。从一个最小的 XML 文档开始。显示
repr(xml_doc)
。显示repr(zlib_compress_output)。在 Flex 脚本(的简化版本)中,使用与repr()
最接近的函数/方法来显示:event.result
、event.result.toString()
和writeUTF*()
的结果。确保您了解 zlib.compress() 之后可能发生的所有事情的影响。仔细阅读文档可能会有所帮助。(2) 看看如何从 event.result 中获取原始字节。
哈特哈,
约翰
What is
byteArray.writeUTF( event.result.toString() );
supposed to do? The result of zlib.compress() is neither unicode nor "UTF" (meaningless without a number after it!?); it is binary aka raw bytes; you should neither decode it nor encode it nor apply any other transformation to it. The receiver should decompress immediately the raw bytes that it receives, in order to recover the data that was passed to zlib.compress().Update What documentation do you have to support the notion that
byteArray.uncompress()
is expecting a true zlib stream and not a deflate stream (i.e. a zlib stream after you've snipped the first 2 bytes and the last 4)?The Flex 3 documentation of ByteArray gives this example:
bytes.uncompress(CompressionAlgorithm.DEFLATE);
but unhelpfully doesn't say what the default (if any) is. If there is a default, it's not documented anywhere obvious, so it would be a very good idea for you to use
bytes.uncompress(CompressionAlgorithm.ZLIB);
to make it obvious what you intend.
AND the docs talk about a
writeUTFBytes
method, not awriteUTF
method. Are you sure that you copy/pasted the exact receiver code in your question?Update 2
Thanks for the URL. Looks like I got hold of the "help", not the real docs :=(. A couple of points:
(1) Yes, there is an explicit
inflate()
method. However uncompress DOES have an algorithm arg; it can be either CompressionAlgorithm.ZLIB (the default) or CompressionAlgorithm.DEFLATE ... interestingly the latter is however only available in Adobe Air, not in Flash Player. At least we know the uncompress() call appears OK, and we can get back to the problem of getting the raw bytes onto the wire and off again into a ByteArray instance.(2) More importantly, there are both
writeUTF
(Writes a UTF-8 string to the byte stream. The length of the UTF-8 string in bytes is written first, as a 16-bit integer, followed by the bytes representing the characters of the string) andwriteUTFBytes
(Writes a UTF-8 string to the byte stream. Similar to the writeUTF() method, but writeUTFBytes() does not prefix the string with a 16-bit length word).Whatever the merits of supplying UTF8-encoded bytes (nil, IMHO), you don't want a 2-byte length prefix there; using writeUTF() is guaranteed to cause uncompress() to bork.
Getting it on to the wire: using Python print on binary data doesn't seem like a good idea (unless sys.stdout has been nobbled to run in raw mode, which you didn't show in your code).
Likewise doing event.result.toString() getting a string (similar to a Python unicode object, yes/no?) -- with what and then encoding it in UTF-8 seem rather unlikely to work.
Given I didn't know that flex existed until today, I really can't help you effectively. Here are some further suggestions towards self-sufficiency in case nobody who knows more flex comes along soon:
(1) Do some debugging. Start off with a minimal XML document. Show
repr(xml_doc)
. Showrepr(zlib_compress_output)
. In (a cut-down version of) your flex script, use the closest function/method torepr()
that you can find to show:event.result
,event.result.toString()
and the result ofwriteUTF*()
. Make sure you understand the effects of everything that can happen after zlib.compress(). Reading the docs carefully may help.(2) Look at how you can get raw bytes out of event.result.
HTH,
John