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?