Flex 3 Close UrlLoader создает исключение

Я пытаюсь смоделировать метод "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 ответа

Решение

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

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

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

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

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

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

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

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

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

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

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

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

setTimeout(unload,1);

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

unload();

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

Вот этот:

private var _loader:URLStream;

И этот:

_loader = new URLStream(); 

И все готово.

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

_loader.close();

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

Майк

Другие вопросы по тегам