Распакуйте строку Zlib при использовании ByteArrays - PullRequest
4 голосов
/ 02 декабря 2009

У меня есть веб-приложение, разработанное в Adobe Flex 3 и Python 2.5 (развернуто в Google App Engine). Веб-служба RESTful была создана в Python, и ее результаты в настоящее время представлены в формате XML, который читается Flex с помощью объекта HttpService.

Теперь основная цель - сжать XML, чтобы между методом send () HttpService и событиями результата было как можно меньше времени. Я просмотрел документы 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 означает, что сгенерированный необработанный байтовый питон не был записан в byteArray должным образом.

- Шри

1 Ответ

2 голосов
/ 02 декабря 2009

Что должен делать byteArray.writeUTF( event.result.toString() );? Результат zlib.compress () не является ни юникодом, ни "UTF" (бессмысленно без числа после него !?); это двоичный файл, то есть необработанные байты; Вы не должны ни декодировать это, ни кодировать это, ни применять любое другое преобразование к нему. Получатель должен немедленно распаковать необработанные байты, которые он получает, чтобы восстановить данные, которые были переданы zlib.compress ().

Обновление Какая документация у вас есть, чтобы поддержать идею о том, что byteArray.uncompress() ожидает истинный поток zlib , а не поток deflate (т.е. zlib поток после того, как вы удалили первые 2 байта и последние 4)?

Документация по Flex 3 ByteArray приводит следующий пример:

bytes.uncompress(CompressionAlgorithm.DEFLATE);

но бесполезно не говорит, какое значение по умолчанию (если есть). Если есть значение по умолчанию, оно нигде не задокументировано, поэтому было бы неплохо использовать

bytes.uncompress(CompressionAlgorithm.ZLIB);

чтобы было понятно, что вы собираетесь.

И в документах говорится о writeUTFBytes методе, а не writeUTF. Вы уверены, что скопировали / вставили точный код получателя в свой вопрос?

Обновление 2

Спасибо за URL. Похоже, я получил «помощь», а не реальные документы: = (. Пара моментов:

(1) Да, существует явный метод inflate(). Однако у несжатого есть алгоритм arg; это может быть либо CompressionAlgorithm.ZLIB (по умолчанию), либо CompressionAlgorithm.DEFLATE ... Интересно, что последний, однако, доступен только в Adobe Air, но не в Flash Player. По крайней мере, мы знаем, что вызов uncompress () выглядит нормально, и мы можем вернуться к проблеме получения необработанных байтов на провод и повторного отключения в экземпляре ByteArray.

(2) Что еще более важно, есть оба writeUTF (Записывает строку UTF-8 в поток байтов. Длина строки UTF-8 в байтах записывается первой, как 16 -битное целое число, за которым следуют байты, представляющие символы строки) и writeUTFBytes (записывает строку UTF-8 в поток байтов. Аналогично методу writeUTF (), но метод writeUTFBytes () делает не префикс строки с 16-битным словом длины).

Какими бы ни были преимущества предоставления байтов в кодировке UTF8 (nil, IMHO), вам не нужен префикс длины в 2 байта; использование writeUTF () гарантированно приведет к тому, что uncompress () не будет работать .

Начало работы: использование печати Python для двоичных данных не кажется хорошей идеей (если только sys.stdout не запущен в режиме raw, который вы не показывали в своем коде).

Аналогично, с помощью метода event.result.toString (), получающего строку (похожего на юникодный объект Python, да / нет?) - с чем и затем кодировать ее в UTF-8, скорее всего, не получится.

Учитывая, что я не знал, что гибкость существовала до сегодняшнего дня, я действительно не могу помочь вам эффективно. Вот некоторые дальнейшие предложения относительно самодостаточности в случае, если никто, кто знает больше гибкости, не появится в ближайшее время:

(1) Выполнить некоторую отладку. Начните с минимального XML-документа. Шоу repr(xml_doc). Шоу repr(zlib_compress_output). В (сокращенной версии) вашего гибкого сценария используйте ближайшую функцию / метод к repr(), которую вы можете найти, чтобы показать: event.result, event.result.toString() и результат writeUTF*(). Убедитесь, что вы понимаете последствия всего, что может произойти после zlib.compress (). Внимательное прочтение документации может помочь.

(2) Посмотрите, как вы можете получить необработанные байты из event.result.

НТН, John

...