【问题标题】:Download a file with Adobe AIR使用 Adob​​e AIR 下载文件
【发布时间】:2010-09-25 11:21:17
【问题描述】:

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

我尝试使用将 url 设置为地址的文件,但是当我尝试保存文件时出现文件不存在错误。并且在这个问题上很难通过 Google 寻求帮助。

【问题讨论】:

    标签: apache-flex actionscript air


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您想从 2 个 api 组合中进行选择来完成此操作。

      版本 1 是 URLLoader 和 FileStream

      使用这个类组合,您可以通过 URLLoader 对象将文件从您的服务器加载到空中。这会将文件下载到内存中,然后在下载完成时通知您。确保使用 URLLoaderDataFormat.BINARY 的 dataFormat 启动下载。然后,您将启动一个 Filestream 对象并使用 writeBytes() 将其写入磁盘。

      版本 2 是 URLStream 和 FileStream

      URLStream 与 URLLoader 非常相似,但不是在使用结果之前等待文件完全下载,而是在下载期间为您提供数据。此方法适用于大文件,因为您不必等待完整下载开始将其保存到磁盘,并且您还可以节省内存,因为一旦播放器将其交给您,它就可以释放与该数据相关的内存.你会以完全相同的方式使用文件流,你最终会在文件流入时对文件的每个块执行 writeBytes()。

      【讨论】:

      • 我想补充一点: 1. 如果我们使用 URLStream 加载一些文件并且不使用 FileStream 将其写入文件 - 应用程序的大小会增长到我们加载的文件的大小。但是,如果我们从流中读取字节并将它们写入文件 - 一切正常。应用程序不会增长。要获取应用程序大小,请使用 System.privateMemory。
      • @Seanalltogether,你能举个例子,但不使用包吗?
      【解决方案3】:

      基于 seanaltogether 的第二个想法,这里有一个函数应该从 Internet 下载文件,并将其保存到磁盘(以桌面上指定的文件名):

      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。

      【讨论】:

        【解决方案4】:

        我使用了 seanaltoggether 的答案,并编写了这个类来处理文件下载。

        这很简单。创建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
                }
            }
        }}
        

        【讨论】:

        【解决方案5】:

        还请检查 URLLoader 类以下载文件。一个很好的例子在这里:http://www.adobe.com/devnet/air/flex/articles/exploring_file_capabilities.html

        与 URLStream 类相比,这对我来说非常快,因为 URLStream 类需要很长时间,并且需要大量 CPU 来下载文件。

        【讨论】:

          猜你喜欢
          • 2012-03-25
          • 2010-12-19
          • 1970-01-01
          • 1970-01-01
          • 2019-08-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多