使用Adobe AIR下载文件

18

如何在基于Flex的AIR应用程序中从Internet上下载文件。

我尝试使用URL设置为地址的文件,但在尝试保存时出现了“文件不存在”的错误。而且很难通过谷歌搜索找到解决此问题的帮助。

5个回答

25

你需要从两个API组合中选择一个来完成此任务。

版本1是URLLoader和FileStream。

使用这两个类的组合,你可以通过URLLoader对象将文件从服务器加载到Air中。这将把文件下载到内存中,然后在下载完成时通知您。请确保使用URLLoaderDataFormat.BINARY数据格式初始化下载。然后,您需要初始化一个Filestream对象,并使用writeBytes()函数将其写入磁盘。

版本2是URLStream和FileStream。

URLStream与URLLoader非常相似,但它不需要在完全下载文件之后才使用结果。在下载过程中,数据就可以被提供给您使用。这种方法适用于大型文件,因为您不必等待完整的下载以开始将其保存到磁盘中,并且还可以节省内存,因为一旦播放器将其交给您,就可以释放相关数据的内存。您将以完全相同的方式使用filestream,只是在流式传输的每个文件块上执行writeBytes()函数。


1
我想添加:1. 如果我们使用URLStream加载某个文件,但不使用FileStream将其写入文件,则应用程序的大小会增长到我们加载的文件大小。但是,如果我们从流中读取字节并将它们写入文件,则一切正常。应用程序不会增长。要获取应用程序大小,请使用System.privateMemory。 - yozhik
@Seanalltogether,您能举个不使用包的例子吗? - Papa De Beau

14
我使用了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
        }
    }
}}

场景1,图层“Layer 1”,帧1,行1 1137:参数数量不正确。预期不超过0个。 所使用的代码:var downloader = new FileDownloader(“http://edvizenor.com/upload/php/files/ImmaculateMary.mp3”,“happy”); downloader.load(); - Papa De Beau

7
为了扩展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);

}

注意:此解决方案使用Prototype和AIRAliases.js。

0

0

请查看flash.net.URLRequest类,它将帮助您下载文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接