AIR File Download Gotcha

If you happen to work with Adobe AIR at some point, and you want to download a file from a server, you may run into this helpful error:

I/O error 2038

Not very helpful. After a lot of digging and trying out solutions, I think I've figured it out. I was doing something like this in a Delegate object:


public function downloadFile( fileName:String ):void {
    var req:URLRequest = new URLRequest( this.sharedFileDownloadURL + fileName );
    var file = new File();
    file.addEventListener( Event.COMPLETE, saveCompleteHandler );
    file.addEventListener( IOErrorEvent.IO_ERROR, ioErrorHandler );
    file.download( req, fileName );
}

The problem seems to be the scope of the File object that is used to perform the download. Because it is locally scoped to that method, when the download completes and the completion event is announced, the file object is essentially gone. I'm not sure if AIR is garbage collecting it, or if the variable is just not accessible because it is function-scoped. Either way, I got this error over and over and was pulling my hair out.

The solution is to not var scope the new File object. Unfortunately that seems to open up potential concurrency issues. Because the Delegate object is essentially a Singlton, if I add the file as a public property of the Delegate, and more than one upload goes at the same time on the client, it will get overwritten. That's not good.

I got around it by creating an Object to wrap around my file called SharedFile. This object has a public property which is a File object. In that case, I can do something like this:


public function downloadFile( sharedFile:SharedFile ):void {
    var req:URLRequest = new URLRequest( this.sharedFileDownloadURL + sharedFile.name );
    sharedFile.file = new File();
    sharedFile.file.addEventListener( Event.COMPLETE, saveCompleteHandler );
    sharedFile.file.addEventListener( IOErrorEvent.IO_ERROR, ioErrorHandler );
    sharedFile.file.download( req, sharedFile.name );
}

So I'm setting the sharedFile.file property to a new File, then using that file object to perform the upload. The I/O error vanishes because the file object is not locally-scoped, and so a reference to it still exists when the completion event fires. Again, I'm not sure of the exact underlying cause of the problem, whether a function-scoped file object is simply not visible when the completion event fires, or whether the AIR runtime is garbage collecting the variable before the completion event fires. Either way, this seems to fix it!

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Raymond Camden's Gravatar Interesting. When I saw the title, I thought you were referring to people downloading AIR files from a web server. I ran into that on my site. Turned out to simply be IIS not knowing what to do with the extension.
# Posted By Raymond Camden | 8/30/08 4:47 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1. Contact Blog Owner