示例:上载和下载文件



FileIO 示例说明了在 Flash Player 中执行文件下载和上载的方法。这些方法包括:

  • 将文件下载到用户的计算机

  • 将文件从用户的计算机上载到服务器

  • 取消正在进行的下载

  • 取消正在进行的上载

若要获取此范例的应用程序文件,请参阅 www.adobe.com/go/learn_programmingAS3samples_flash_cn。在 Samples/FileIO 文件夹中可以找到 FileIO 应用程序文件。该应用程序包含以下文件:

文件

描述

FileIO.fla

FileIO.mxml

Flash 或 Flex 中的主应用程序文件(分别为 FLA 和 MXML)。

com/example/programmingas3/fileio/FileDownload.as

一个类,包含用于从服务器下载文件的方法。

com/example/programmingas3/fileio/FileUpload.as

一个类,包含用于将文件上载到服务器的方法。

FileIO 应用程序概述

FileIO 应用程序包含用户界面,使用户可以使用 Flash Player 上载或下载文件。该应用程序首先定义一对自定义组件 FileUpload 和 FileDownload,可以在 com.example.programmingas3.fileio 包中找到这两个组件。每个自定义组件调度其 contentComplete 事件后,会调用该组件的 init() 方法,此方法传递对 ProgressBar 和 Button 组件实例的引用,从而使用户可以看到文件的上载或下载进度或者取消正在进行的文件传输。

FileIO.mxml 文件中的相关代码如下所示(请注意,在 Flash 版本中,FLA 文件包含放在舞台上的组件,这些组件的名称与此步骤中介绍的 Flex 组件的名称相匹配):

<example:FileUpload id="fileUpload" creationComplete="fileUpload.init(uploadProgress, cancelUpload);" /> 
<example:FileDownload id="fileDownload" creationComplete="fileDownload.init(downloadProgress, cancelDownload);" />

下面的代码显示“上载文件”面板,其中包含一个进度条和两个按钮。第一个按钮 startUpload 调用 FileUpload.startUpload() 方法,该方法调用 FileReference.browse() 方法。下面的摘选显示了用于“上载文件”面板的代码:

<mx:Panel title="Upload File" paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"> 
    <mx:ProgressBar id="uploadProgress" label="" mode="manual" /> 
    <mx:ControlBar horizontalAlign="right"> 
        <mx:Button id="startUpload" label="Upload..." click="fileUpload.startUpload();" /> 
        <mx:Button id="cancelUpload" label="Cancel" click="fileUpload.cancelUpload();" enabled="false" /> 
    </mx:ControlBar> 
</mx:Panel>

此代码将一个 ProgressBar 组件实例和两个 Button 组件按钮实例放在舞台上。当用户单击“上载”按钮 (startUpload) 时,会启动一个操作系统对话框,允许用户选择要上载到远程服务器的文件。尽管用户开始文件上载时,另一个按钮 cancelUpload 会变为可用,并允许用户随时中断文件传输,但默认情况下禁用该按钮。

用于“下载文件”面板的代码如下:

<mx:Panel title="Download File" paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"> 
    <mx:ProgressBar id="downloadProgress" label="" mode="manual" /> 
    <mx:ControlBar horizontalAlign="right"> 
        <mx:Button id="startDownload" label="Download..." click="fileDownload.startDownload();" /> 
        <mx:Button id="cancelDownload" label="Cancel" click="fileDownload.cancelDownload();" enabled="false" /> 
    </mx:ControlBar> 
</mx:Panel>

此代码与文件上载代码非常相似。当用户单击“下载”按钮 (startDownload) 时,会调用 FileDownload.startDownload() 方法,从而开始下载 FileDownload.DOWNLOAD_URL 变量中指定的文件。在文件下载时,进度条进行更新,以显示文件下载百分比。用户可以随时通过单击 cancelDownload 按钮取消下载,这样会立即停止正在进行的文件下载。

从远程服务器下载文件

从远程服务器下载文件由 flash.net.FileReference 类和自定义 com.example.programmingas3.fileio.FileDownload 类处理。当用户单击“下载”按钮时,Flash Player 开始下载 FileDownload 类的 DOWNLOAD_URL 变量中指定的文件。

FileDownload 类从定义 com.example.programmingas3.fileio 包中的 4 个变量开始,如以下代码所示:

    /** 
     * Hard-code the URL of file to download to user's computer. 
     */ 
    private const DOWNLOAD_URL:String = "http://www.yourdomain.com/file_to_download.zip"; 
 
    /** 
     * Create a FileReference instance to handle the file download. 
     */ 
    private var fr:FileReference; 
 
    /** 
     * Define reference to the download ProgressBar component. 
     */ 
    private var pb:ProgressBar; 
 
    /** 
     * Define reference to the "Cancel" button which will immediately stop 
     * the current download in progress. 
     */ 
    private var btn:Button;

第一个变量 DOWNLOAD_URL 包含文件的路径,当用户单击主应用程序文件中的“下载”按钮时,该文件会下载到用户的计算机上。

第二个变量 fr 是 FileReference 对象,该对象在 FileDownload.init() 方法中进行初始化,用于处理远程文件到用户计算机的下载。

最后两个变量 pbbtn 包含对舞台上的 ProgressBar 和 Button 组件实例的引用,它们由 FileDownload.init() 方法进行初始化。

初始化 FileDownload 组件

通过在 FileDownload 类中调用 init() 方法对 FileDownload 组件进行初始化。此方法使用两个参数 pbbtn,它们分别是 ProgressBar 和 Button 组件实例。

用于 init() 方法的代码如下所示:

    /** 
     * Set references to the components, and add listeners for the OPEN,  
     * PROGRESS, and COMPLETE events. 
     */ 
    public function init(pb:ProgressBar, btn:Button):void 
    { 
        // Set up the references to the progress bar and cancel button, 
        // which are passed from the calling script. 
        this.pb = pb; 
        this.btn = btn; 
 
        fr = new FileReference(); 
        fr.addEventListener(Event.OPEN, openHandler); 
        fr.addEventListener(ProgressEvent.PROGRESS, progressHandler); 
        fr.addEventListener(Event.COMPLETE, completeHandler); 
    }

开始文件下载

当用户单击舞台上的 Download Button 组件实例时,startDownload() 方法启动文件下载进程。下面的摘选显示了 startDownload() 方法:

    /** 
     * Begin downloading the file specified in the DOWNLOAD_URL constant. 
     */ 
    public function startDownload():void 
    { 
        var request:URLRequest = new URLRequest(); 
        request.url = DOWNLOAD_URL; 
        fr.download(request); 
    }

首先,startDownload() 方法创建一个新的 URLRequest 对象,并将目标 URL 设置为 DOWNLOAD_URL 变量指定的值。接下来,调用 FileReference.download() 方法,将新创建的 URLRequest 对象作为参数传递。这会导致操作系统在用户计算机上显示一个对话框,提示用户选择一个位置以保存所请求的文档。用户选择了位置后,将调度 open 事件 (Event.OPEN) 并调用 openHandler() 方法。

openHandler() 方法设置 ProgressBar 组件的 label 属性的文本格式,并启用使用户可以立即停止正在进行的下载的“取消”按钮。openHandler() 方法如下所示:

    /** 
     * When the OPEN event has dispatched, change the progress bar's label  
     * and enable the "Cancel" button, which allows the user to abort the  
     * download operation. 
     */ 
    private function openHandler(event:Event):void 
    { 
        pb.label = "DOWNLOADING %3%%"; 
        btn.enabled = true; 
    }

监视文件的下载进度

当从远程服务器向用户计算机下载文件时,会定期调度 progress 事件 (ProgressEvent.PROGRESS)。每当调度 progress 事件时,会调用 progressHandler() 方法并更新舞台上的 ProgressBar 组件实例。用于 progressHandler() 方法的代码如下所示:

    /** 
     * While the file is downloading, update the progress bar's status. 
     */ 
    private function progressHandler(event:ProgressEvent):void 
    { 
        pb.setProgress(event.bytesLoaded, event.bytesTotal); 
    }

进度事件包含两个属性(bytesLoadedbytesTotal),这两个属性用于更新舞台上的 ProgressBar 组件。这样,用户可以了解已完成下载的文件比例以及尚未下载的文件比例。用户可以通过单击进度条下的“取消”按钮随时终止文件传输。

如果文件下载成功,complete 事件 (Event.COMPLETE) 将调用 completeHandler() 方法,该方法通知用户文件已完成下载并禁用“取消”按钮。用于 completeHandler() 方法的代码如下所示:

    /** 
     * Once the download has completed, change the progress bar's label one  
     * last time and disable the "Cancel" button since the download is  
     * already completed. 
     */ 
    private function completeHandler(event:Event):void 
    { 
        pb.label = "DOWNLOAD COMPLETE"; 
        btn.enabled = false; 
    }

取消文件下载

用户可以通过单击舞台上的“取消”按钮随时终止文件传输和停止下载任何更多字节。下面的摘选显示了用于取消下载的代码:

    /** 
     * Cancel the current file download. 
     */ 
    public function cancelDownload():void 
    { 
        fr.cancel(); 
        pb.label = "DOWNLOAD CANCELLED"; 
        btn.enabled = false; 
    }

首先,该代码立即停止文件传输以禁止继续下载任何数据。接下来,进度条的 label 属性进行更新,通知用户下载已成功取消。最后,禁用“取消”按钮,从而阻止用户再次尝试下载文件之前再次单击该按钮。

将文件上载到远程服务器上

文件上载进程与文件下载进程非常相似。FileUpload 类声明相同的四个变量,如以下代码所示:

private const UPLOAD_URL:String = "http://www.yourdomain.com/your_upload_script.cfm"; 
private var fr:FileReference; 
private var pb:ProgressBar; 
private var btn:Button;

FileDownload.DOWNLOAD_URL 变量不同,UPLOAD_URL 变量包含要从用户计算机上载文件的服务器端脚本的 URL。其余三个变量的作用与 FileDownload 类中的对应变量相同。

初始化 FileUpload 组件

FileUpload 组件包含 init() 方法,此方法从主应用程序调用。此方法使用两个参数 pbbtn,它们是对舞台上的 ProgressBar 和 Button 组件实例的引用。接下来,init() 方法初始化先前在 FileUpload 类中定义的 FileReference 对象。最后,此方法将四个事件侦听器分配给 FileReference 对象。用于 init() 方法的代码如下所示:

public function init(pb:ProgressBar, btn:Button):void 
{ 
    this.pb = pb; 
    this.btn = btn; 
 
    fr = new FileReference(); 
    fr.addEventListener(Event.SELECT, selectHandler); 
    fr.addEventListener(Event.OPEN, openHandler); 
    fr.addEventListener(ProgressEvent.PROGRESS, progressHandler); 
    fr.addEventListener(Event.COMPLETE, completeHandler); 
}

开始文件上载

当用户单击舞台上的“上载”按钮时,启动文件上载,此操作将调用 FileUpload.startUpload() 方法。此方法调用 FileReference 类的 browse() 方法,从而导致操作系统显示一个系统对话框,以提示用户选择要上载到远程服务器的文件。下面的摘选显示了用于 startUpload() 方法的代码:

public function startUpload():void 
{ 
    fr.browse(); 
}

在用户选择要上载的文件后,会调度 select 事件 (Event.SELECT),从而导致调用 selectHandler() 方法。selectHandler() 方法新建一个 URLRequest 对象,并将 URLRequest.url 属性设置为先前在代码中定义的 UPLOAD_URL 常量的值。最后,FileReference 对象将所选文件上载到指定的服务器端脚本。用于 selectHandler() 方法的代码如下所示:

private function selectHandler(event:Event):void 
{ 
    var request:URLRequest = new URLRequest(); 
    request.url = UPLOAD_URL; 
    fr.upload(request); 
}

FileUpload 类中的其余代码与 FileDownload 类中定义的代码相同。如果用户想要在任何时间点终止上载,可以单击“取消”按钮,该按钮将在进度条上设置标签并立即停止文件传输。每当调度 progress 事件 (ProgressEvent.PROGRESS) 时,都会更新进度条。同样,当完成上载时,进度条进行更新以通知用户文件已上载成功。然后,禁用“取消”按钮,直到用户开始新的文件传输。