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.