Загрузка файла с помощью Adobe AIR
Как загрузить файл из интернета в приложении Flex на основе AIR.
Я попытался использовать файл с url-адресом, но я получил файл не существует ошибка, когда я пытался сохранить его. И это действительно трудно google для помощи по этому вопросу.
5 ответов
вы хотите выбрать один из 2 API комбо для достижения этой цели.
Версия 1-URLLoader и FileStream
используя эту комбинацию классов, вы загрузите файл с вашего сервера в air через объект URLLoader. Это загрузит файл в память, а затем уведомит вас, когда загрузка будет завершена. Убедитесь, что вы инициируете загрузку с помощью dataFormat URLLoaderDataFormat.ДВОИЧНЫЙ. Затем вы инициируете объект Filestream и записываете его на диск используя writeBytes().
Версия 2-URLStream и FileStream
URLStream очень похож на URLLoader, но вместо того, чтобы ждать полной загрузки файла перед использованием результата, данные становятся доступными вам во время загрузки. Этот метод хорошо работает для больших файлов, потому что вам не нужно ждать полной загрузки, чтобы начать сохранять его на диск, а также экономить память, так как после того, как игрок передаст его вам, он может освободить память, связанную с этим данные. Вы бы использовали filestream точно так же, вы бы просто делали writeBytes() на каждом куске файла, когда он течет.
я использовал ответ seanalltogether и написал этот класс для обработки загрузки файлов.
- Это довольно просто. создать var downloader = new FileDownloader("url", "Local/Path");
и звонок downloader.load()
начать скачивание.
Он также поддерживает установку функции, которая будет вызываться, когда сделано, и в точках во время загрузки. Передача функции onProgress количество байтов, которые были загружены. ( Я не мог понять, как получить фракцию, так как я не мог понять, как запросить размер файла раньше он был загружен)
package com.alex{
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
{
// 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(t:uint):void{};
public var onComplete :Function = function():void{};
public var remotePath :String = "";
public var localFile :File = null;
private 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 {
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();
onComplete();
}
});
fileAccess.openAsync( localFile, FileMode.WRITE );
stream.addEventListener( "progress" , function () :void {
var bytes :ByteArray = new ByteArray();
var thisStart :uint = currentPosition;
currentPosition += stream.bytesAvailable;
// ^^ Makes sure that asyncronicity does not break anything
stream.readBytes( bytes, thisStart );
fileAccess.writeBytes( bytes, thisStart );
onProgress( currentPosition );
});
stream.addEventListener( "complete", function () :void {
downloadCompleteFlag = true;
});
stream.load( requester );
} else {
// Do something unspeakable
}
}
}}
чтобы построить на второй идее seanalltogether, вот функция, которая должна загрузить файл из интернета и сохранить его на диск (в указанном имени файла на рабочем столе):
downloadFile: function (url, fileName) {
var urlStream = new air.URLStream();
var request = new air.URLRequest(url);
var fileStream = new air.FileStream();
// write 50k from the urlstream to the filestream, unless
// the writeAll flag is true, when you write everything in the buffer
function writeFile(writeAll) {
if (urlStream.bytesAvailable > 51200 || writeAll) {
alert("got some");
var dataBuffer = new air.ByteArray();
urlStream.readBytes(dataBuffer, 0, urlStream.bytesAvailable);
fileStream.writeBytes(dataBuffer, 0, dataBuffer.length);
}
// do clean up:
if (writeAll) {
alert("done");
fileStream.close();
urlStream.close();
// set up the next download
setTimeout(this.downloadNextFile.bind(this), 0);
}
}
urlStream.addEventListener(air.Event.COMPLETE, writeFile.bind(this, true));
urlStream.addEventListener(air.ProgressEvent.PROGRESS, writeFile.bind(this, false));
var file = air.File.desktopDirectory.resolvePath(fileName);
fileStream.openAsync(file, air.FileMode.WRITE);
urlStream.load(request);
}
Примечание: это решение использует прототип и AIRAliases.js.
пожалуйста, также проверьте класс URLLoader для загрузки файлов. Отличный пример здесь: http://www.adobe.com/devnet/air/flex/articles/exploring_file_capabilities.html
Это получилось очень быстро для меня, по сравнению с классом URLStream, который занимал века, и много процессора для загрузки файлов.