Goje87
Goje87

Reputation: 2869

URLStream throws Error#2029 in my flex AIR app

In my AIR app, I am trying to implement a file downloader using URLStream.

public class FileDownloader {       
        // Class to download files from the internet

        // Function called every time data arrives
        // called with an argument of how much has been downloaded
        public var onProgress :Function = function(loaded:Number, total:Number):void{};
        public var onComplete :Function = function():void{};
        public var remotePath :String = "";
        public var localFile :File = null; 
        public var running:Boolean = false;

        public var stream :URLStream;
        private var fileAccess :FileStream;

        public function FileDownloader( remotePath :String = "" , localFile :File = null ) {            
            this.remotePath = remotePath;
            this.localFile = localFile;
        }

        public function load() :void 
        {
            try
            {
                stream = null;
                if( !stream || !stream.connected ) 
                {
                    stream = new URLStream();
                    fileAccess = new FileStream();

                    var requester :URLRequest = new URLRequest( remotePath );
                    var currentPosition :uint = 0;
                    var downloadCompleteFlag :Boolean = false;

                    // Function to call oncomplete, once the download finishes and
                    // all data has been written to disc                               
                    fileAccess.addEventListener( "outputProgress", function ( result ):void {
                        if( result.bytesPending == 0 && downloadCompleteFlag ) {                        
                            stream.close();
                            fileAccess.close();
                            running = false;
                            onComplete();
                        }
                    });


                    fileAccess.openAsync( localFile, FileMode.WRITE );

                    fileAccess.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent)
                    {
                        trace('remotePath: '+remotePath);
                        trace('io error while wrintg ....'+e.toString());
                    });

                    stream.addEventListener(IOErrorEvent.IO_ERROR, function(e:IOErrorEvent)
                    {
                        trace('remotePath: '+remotePath);
                        trace('There was an IO error with the stream: '+e.text);
                    });

                    stream.addEventListener( "progress" , function (e:ProgressEvent) :void {
                        var bytes :ByteArray = new ByteArray();
                        var thisStart :uint = currentPosition;
                        currentPosition += stream.bytesAvailable;
                        // ^^  Makes sure that asyncronicity does not break anything

                        try
                        {
                            //trace('reading from '+remotePath+' ...');
                            stream.readBytes( bytes, thisStart );
                            fileAccess.writeBytes( bytes, thisStart );
                        }
                        catch(err:Error)
                        {
                            trace('remotePath: '+remotePath);
                            trace('error while writing bytes from...'+err.name+':'+err.message);
                            if(stream.connected)
                                stream.close();

                            abort();
                            onComplete();
                            return;
                        }

                        onProgress( e.bytesLoaded, e.bytesTotal );                                          
                    });

                    stream.addEventListener( "complete", function () :void {
                        downloadCompleteFlag = true;
                    });

                    stream.load( requester );

                } else {
                    // Do something unspeakable
                }
                running = true;
            }
            catch(err:Error)
            {
                trace('error while downloading the file: '+err);
            }
        }

        public function abort():void {
            try {
                stream.close();
                trace('stream closed');
                running = false;
            }
            catch(err:Error) {
                trace('error while aborting download');
                trace(err);
            }
        }
    }

I simply create an object of the above class and passing the url and the file and call the load function. For some files I get the following error.

remotePath: http://mydomain.com/238/6m_608-450.jpg
error while writing bytes from...Error:Error #2029: This URLStream object does not have a stream opened.

Which means the error is from the file stream(fileAccess) that I am using. I am unable to figure out why this could be happening. If I try to open the url http://mydomain.com/238/6m_608-450.jpg in the browser, it opens properly. This happens randomly for some files. What could be the problem?

Upvotes: 0

Views: 3201

Answers (1)

kero_zen
kero_zen

Reputation: 694

I have tried in my office and it works for me (for differents files and filesize). So, can you describe the files (or types files) which don't work for you (post an url if you can) ? I would say that when you use the method readBytes your stream (so the URLStream) is ever close.

More, I allows me some advice : 1/ Use flash's constants instead of simple string 2/ Don't forget to remove your listeners once the operation completed 3/ Your method FileDownloader is quite confusing. Use lowercase if it's a function or puts a capital letter with class's name if you use it as a constructor. For me, this function must be a constructor.

Upvotes: 1

Related Questions