Carlos Gustavo (The Froskie) Internet, web, www…

2out/090

Download de arquivos com Adobe AIR

Em um projeto recente em Flex/AIR, um player em um thin client precisava tocar vídeos, áudios e imagens que vinham de uma central. Havia a necessidade de fazer isso offline para que não torrasse banda. Então precisei de uma classe que faria o download de um arquivo, vindo de uma URL, para dentro da pasta de armazenamento da aplicação (applicationStoreDirectory):

package 
{
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.ProgressEvent;
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import flash.net.URLRequest;
    import flash.net.URLStream;
    import flash.utils.ByteArray;
 
 
    public class FileDownloader extends EventDispatcher
    {    
        // url do arquivo
        private var fileURL:String;
 
        // url stream do arquivo
        private var urlStream:URLStream;
 
        // file stream do arquivo
        private var fileStream:FileStream;
 
        // referencia fisica do arquivo completo
        private var fileRef:File;
 
        public function FileDownloader(){
 
            // inicia os streams
            urlStream = new URLStream();
            fileStream = new FileStream();
 
            // eventos da URL
            urlStream.addEventListener(Event.COMPLETE, this.onComplete);
            urlStream.addEventListener(ProgressEvent.PROGRESS, this.onProgress);
        }
 
        public function download(url:String):void{
            // referencia o caminho do arquivo
            fileURL = url;
 
            // abre o filestream do arquivo
            urlStream.load(new URLRequest(fileURL));
 
        }
        private function onProgress(ev:ProgressEvent):void{
            // para uso de barra de progresso, porcentagem, etc.
            this.dispatchEvent(ev);
        }
 
        private function onComplete(ev:Event):void{
            // separa o nome do arquivo
            var urlParams:Array = fileURL.split("/");
            urlParams.reverse();
 
            // cria a referencia dos arquivos
            fileRef = File.applicationStorageDirectory.resolvePath(urlParams[0]);
 
            // abre o arquivo para escrita
            fileStream.open(fileRef, FileMode.WRITE);
 
            var byteArray:ByteArray = new ByteArray();
            urlStream.readBytes(byteArray, 0, urlStream.bytesAvailable);
 
            // escreve o arquivo temporario
            fileStream.writeBytes(byteArray, 0, byteArray.length);
 
            // fecha as streams
            urlStream.close();
            fileStream.close();
 
            // dispara o evento
            this.dispatchEvent(new Event(Event.COMPLETE));
        }
 
    }
}

Para usá-la, foi bem simples:

var fileDownloader:FileDownloader = new FileDownloader();
fileDownloader.addEventListener(Event.COMPLETE, this.downloadComplete);
fileDownloader.download('http://www.meusite.com/meuarquivo.jpg');
 
function downloadComplete(ev:Event):void{
    // download completo
}

Apenas justificando porque não usei URLLoader ao invéis de URLStream: porque apesar de não ter sido implementado, a classe URLLoader não me daria os bytes já carregados do meu arquivo para que (caso quisesse), fosse escrevendo o arquivo a medida que ele fosse baixado.