Flex 3 Close Urlloader throws anomalies

I am trying to use UrlLoader to simulate the’HEAD’ method; essentially, I just want to check if the file exists without downloading the entire file. I think I will only use HttpStatusEvent, but when you When running in debug mode, the following code throws an exception (I can’t wrap it in a try/catch block).



< br /> 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);
}
}
]]>


I tried to use ProgressEvents, but it seems that some 404 pages return content, so the status event will correctly identify whether the page exists.

Does anyone have an idea?

I think this is an error in the URLLoader class.

If you see an error message (at least the one I got, you didn't paste yorrs!) you will see it:

Error: Error #2029: This URLStream
object does not have a stream opened
at flash.net::URLStream/readBytes()
at flash.net::URLLoader/onComplete()

This can give you an idea of ​​what is going on. The URLLoader class uses a URLStream object internally, which provides low-level access to the downloaded data.

The error message indicates that the onComplete handler is being called on the URLLoader. The file is very Large but it may be cached, so the loading speed is quite fast. Now, if you add listeners for progress and completion events, you will see the order of triggering events is:

>progress
>status
>Done

The docs confirm this:

Note that the httpStatus event (if
any) is sent before (and in addition
to) any complete or error event.

Now, you can see that the problem is from the state handler that you are calling close(). This closes the stream .But obviously (I think it’s an error), the onComplete handler in the URLLoader class will not check if the stream is open. (This can’t be checked from Actionscript, so you have to wrap the code in a try/catch). You can’t close it from The data is read in the stream, so this is the reason for it.

I can see two ways to solve this problem:

1) Delay the execution of calling close() (your Uninstall method) function, so that close() is called after calling the onComplete method inside the URLLoader.

This is it Like:

setTimeout(unload,1);

Instead of this:

unload( );

2) Use URLStream instead of URLLoader. The first option makes me feel a bit like a hacked solution, so in your case I will choose the last one. Usually, using URLStream means More work, but in this case, you are not actually interested in reading any data, so it doesn't make much difference. Also, you only need to change two lines in the current code:

This:

private var _loader:URLStream;

There is also this:

_loader = new URLStream();

And you are all ready.

I am trying to use UrlLoader to simulate the'HEAD' method; essentially, I just want Check if the file exists without downloading the entire file. I think I will only use HttpStatusEvent, but when you run in debug mode, the following code throws an exception (I can't wrap it in a try/catch block).

< /p>

< br />

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 (HTTPStat usEvent.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 functi on statusHandler(event:HTTPStatusEvent):void {
if(event.status.toString().match(/^2/)) {
status.text = "success";
unload ();
}
else {
errorHandler(event);
}
}
]]>


I tried to use ProgressEvents, but it seems that some 404 pages return content, so the status event will correctly identify whether the page exists.< /p>

Does anyone have an idea?

I think this is an error in the URLLoader class.

If you see an error message (at least I get That, you didn’t paste your yorrs!) You will see it:

Error: Error #2029: This URLStream
object does not have a stream opened< br> at flash.net::URLStream/readBytes()
at flash.net::URLLoader/onComplete()

This allows you to understand what is happening. URLLoader class The URLStream object is used internally, which provides low-level access to the downloaded data.

The error message indicates that the onComplete handler is being called on the URLLoader. The file is large but it may be cached, so the loading speed is quite fast Now, if you add a listener for the progress and completion events, you will see the sequence of triggering events is:

>progress
>status
>complete

The docs confirm this:

Note that the httpStatus event (if
any) is sent before (and in addition
to) any complete or error event.

Now, you can see that the problem is from the status handler you are calling close(). This closes the stream. But obviously (I think it’s an error), URLLoader The onComplete handler in the class does not check whether the stream is open. (This cannot be checked from Actionscript, so you have to wrap the code in try/catch). You cannot read data from a closed stream, so this is the reason for it .

I can see two ways to solve this problem:

1) Delay the execution of the function that calls close() (your uninstall method), so that onComplete is called inside the URLLoader Call close() after the method.

That’s it:

setTimeout(unload,1);

instead of this:< /p>

unload();

2) Use URLStream instead of URLLoader. The first option makes me feel a bit like a hacked solution, so in your case I will choose the last one. Usually, using URLStream means more work, but in this case, you are not actually interested in reading any data, so it doesn't make much difference. Also, you only need to change two lines in the current code: /p>

This:

private var _loader:URLStream;

There is also this:

_loader = new URLStream();

And you are all ready.

Leave a Comment

Your email address will not be published.