Flex 3 Close UrlLoader создает исключение - PullRequest
4 голосов
/ 28 мая 2010

Я пытаюсь смоделировать метод 'HEAD' с помощью UrlLoader; по сути, я просто хочу проверить наличие файла без загрузки всего файла. Я подумал, что просто использовал бы HttpStatusEvent, но следующий код выдает исключение (которое я не могу обернуть в блок try / catch) при запуске в режиме отладки.

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="init()">
<mx:Script>
    <![CDATA[

       private static const BIG_FILE:String = "http://www.archive.org/download/gspmovvideotestIMG0021mov/IMG_0021.mov";

       private var _loader:URLLoader;

       private function init():void {
            _loader = new URLLoader();
            _loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, statusHandler);
            _loader.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
            _loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
            _loader.load(new URLRequest(BIG_FILE));   
       }

       public function unload():void { 
            try {
                _loader.close();
                _loader.removeEventListener(HTTPStatusEvent.HTTP_STATUS, statusHandler);
                _loader.removeEventListener(IOErrorEvent.IO_ERROR, errorHandler);
                _loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, errorHandler);
            }
            catch(error:Error) {
                status.text = error.message;
            }
        }

        private function errorHandler(event:Event):void {
            status.text = "error";
            unload();
        }

        private function statusHandler(event:HTTPStatusEvent):void {
            if(event.status.toString().match(/^2/)) {
                status.text = "success";
                unload();
            }
            else {
                errorHandler(event);
            }
        }   
    ]]>
</mx:Script>

<mx:Label id="status" />

Я попытался использовать ProgressEvents вместо этого, но кажется, что около 404 страниц возвращают содержимое, поэтому событие состояния правильно определит, существует ли страница.

У кого-нибудь есть идеи?

Ответы [ 2 ]

6 голосов
/ 30 мая 2010

Это ошибка в классе URLLoader, я думаю.

Если вы прочитаете сообщение об ошибке (по крайней мере, то, которое я получил, вы не вставили yorrs!), Вы увидите его:

Ошибка: ошибка № 2029: этот URLStream у объекта нет открытого потока на flash.net::URLStream/readBytes () на flash.net::URLLoader/onComplete()

Это дает вам некоторое представление о том, что происходит. Класс URLLoader внутренне использует объект URLStream , который обеспечивает низкоуровневый доступ к загруженным данным.

Сообщение об ошибке указывает на то, что обработчик onComplete вызывается на URLLoader. Файл большой, но, вероятно, он кешируется, поэтому загружается довольно быстро. Теперь, если вы добавите прослушиватель для событий хода выполнения и завершения, вы увидите, в каком порядке запускаются события:

  • прогресс
  • статус
  • полная

Документы подтверждают это:

Обратите внимание, что событие httpStatus (если любой) отправляется до (и дополнительно к) любое событие завершения или ошибки.

Теперь вы можете видеть, что проблема в том, что из обработчика состояния вы вызываете close (). Это закрывает поток. Но очевидно (и это ошибка, я думаю), обработчик onComplete в классе URLLoader не проверяет, открыт ли поток или нет. (Из Actionscript нет способа проверить это, поэтому вам придется заключить код в try / catch). Вы не можете читать данные из закрытого потока, поэтому он и дует.

Я вижу 2 способа исправить это:

1) Отложить выполнение функции, которая вызывает close () (ваш метод выгрузки), поэтому close () вызывается после вызывается внутренний метод onComplete URLLoader.

То есть сделать это:

setTimeout(unload,1);

вместо этого:

unload();

2) Используйте URLStream вместо URLLoader. Первый вариант кажется мне хакерским обходным решением, поэтому я бы выбрал последний в вашей ситуации. Использование URLStream в целом означает больше работы на вашей стороне, но в этом случае вы на самом деле не заинтересованы в чтении каких-либо данных, поэтому это не имеет большого значения. Кроме того, вам нужно всего лишь изменить две строки в вашем текущем коде:

Вот этот:

private var _loader:URLStream;

А вот этот:

_loader = new URLStream(); 

И все готово.

1 голос
/ 10 января 2011

Я столкнулся с похожей проблемой.
Проблема в том, что я обнаружил этот вызов:

_loader.close();

Ошибка произошла, когда я попытался закрыть файл, который я даже не открыл. Поэтому в предложении «try» проверьте, открыт ли файл, прежде чем пытаться его закрыть.

Майк

...