flex使用filereference实现文件下传/上载

flex使用filereference实现文件上传/下载
以下是一个.net的实例,(基本和java的相同,出现的问题是一样!)

我们从flex客户端开始,看看客户端是通过什么方式想服务端发起请求。flex客户端要完成文件上传下载都是通过filerefudderence来实现,首先得定义一个该类型对象实例:

private var statetext:string = "请选择一个文件上传";
//通过调用file对象的方法来完成上传和下载功能
private var file:filereference = new filereference();
复制代码
上传文件通常涉及到的有选择文件、上传文件以及上传完成这些最基本的处理过程。ok,下面我们就以这三个过程为例来看看flex是怎么来完成文件的上传功能。首先为这三个功能点分别添加监听事件处理函数 ,在程序

加载时调用:

internal function initapp():void
{
    file.addeventlistener(event.select,onselected);
    file.addeventlistener(event.complete,oncompleted);
    file.addeventlistener(progressevent.progress,onprogress);
}
复制代码
另外我们也可以不用上面这中定义一个函数在程序加载时调用进行初始化操作,应用程序(mxml )的初始化操作又creationcomplete方法完成,另外还有一个比它先执行的方法createchildren(),我们可以直接在mxml下重写该方法来实现应用程序的初始化,如下:

/**
* createchildren 比 creationcomplete 事件更早发生
* */
protected override function createchildren():void
{
    file.addeventlistener(event.select,onselected);
    file.addeventlistener(event.complete,oncompleted);
    file.addeventlistener(progressevent.progress,onprogress);
}
复制代码
这三个事件处理函数的详细定义如下(其中的statetext为string的变量,用于显示文件上传状态提示):

internal function onselected(evt:event):void
{
     statetext = "选择了文件" + file.name;
}

internal function oncompleted(evt:event):void
{
     statetext = "上传完毕!";
}

internal function onprogress(evt:progressevent):void
{
     statetext = "已上传 " + math.round(100 * evt.bytesloaded / evt.bytestotal) + "%";
}
复制代码
到这里客户端就只差一步了,那就是完成发起上传请求的方法,实际上就是通过urlrequest对象创建一个与服务端的连接,然后直接调用fielreference类的upload()方法就可完成该功能,详细如下代码定义:

/**
  * 调用filereference的实例方法upload()实现文件上传
  * */
internal function onupload():void
{
     if(file.size > 0)
     {
         statetext = "正在上传文件:" + file.name;
     }
    var request:urlrequest = new urlrequest();
    request.url="http://localhost/web/uploadhandler.ashx";
    file.upload(request);
}
复制代码
写好了upload方法,现在就是调用他了,通过按扭的click事件直接调用就可以,另外调用file.browse()方法则实现选择文件的功能,如下mxml代码描述:

<mx:textinput x="10" y="57" id="txtfile" text="{statetext}" width="229"/>
<mx:button x="247" y="57" label="选择" fontweight="normal" click="{file.browse()}"/>
<mx:button x="29" y="111" label="上传文件" width="111" fontweight="normal" click="onupload()"/>
复制代码
如上便完成了上传文件的flex客户端开发,通过file.upload()方法,将把选择的文件通过二进制的形式发送到指定的服务端,并自动传递一个叫 “filename”的参数,服务端通过filename便可以接收到客户端请求上传的文件。最后我们来看看服务端的 uploadhandler.ashx的详细定义:

public class uploadhandler : ihttphandler
{
     //文件上传目录
     private string uploadfolder = "upload";

     public void processrequest(httpcontext context)
     {
         context.response.contenttype = "text/plain";

        httpfilecollection files = context.request.files;
        if (files.count > 0)
        {
            string path = context.server.mappath(uploadfolder);
            httppostedfile file = files[0];

            if (file != null && file.contentlength > 0)
            {
                string savepath = path + "/" + context.request.form["filename"];
                file.saveas(savepath);
            }
        }
        else
        {
            context.response.write("参数错误");
            context.response.end();
        }
    }

    public bool isreusable
    {
        get
        {
            return false;
        }
    }
}
复制代码
如上一系列的步骤便可完成上传文件的功能,下面便是上传文件示例程序运行 截图:  



   实现了文件上传下面来看看怎么实现文件下载, 以上面上传示例中上传的mp3为例,下面我们来看看怎么从服务器 (http://localhost/web/upload/做你的爱人.mp3)上完成文件(做你的爱人.mp3)的下载。

     要实现文件下载对服务器端只要保证被下载文件存在就ok,同上传文件一样需要实例化一个fielreference对象的实例,并为其添加相应的事件处理函数:

private var filedown:filereference = new filereference();


/**
  * createchildren 比 creationcomplete 事件更早发生
  * */
protected override function createchildren():void
{
     super.createchildren();
     file.addeventlistener(event.select,onselected);
     file.addeventlistener(event.complete,oncompleted);
     file.addeventlistener(progressevent.progress,onprogress);
    //实现文件下载
    filedown.addeventlistener(event.complete,ondowncompleted);
    filedown.addeventlistener(progressevent.progress,ondownprogress);
}


     如上为实现下载文件的实例filedown注册了成功下载文件后事件处理函数和下载过程处理函数,下面是两个方法的详细定义:

internal function ondowncompleted(evt:event):void
{
     var fileref:filereference = evt.currenttarget as filereference;
     resultlabel.text = "文件名:" + fileref.name + "下载完毕!";
}

internal function ondownprogress(evt:progressevent):void
{
     downstate.text = "已下载: " + math.round(100 * evt.bytesloaded / evt.bytestotal) + "%";
}
复制代码
完成了对象事件的开发,最后便上惩罚下载请求了,直接调用filereference类所提供的download()方法既可:

/**
* 调用filereference类的实例方法download()实现文件下载
* */
internal function ondownload():void
{
    var request:urlrequest = new urlrequest();
    request.url="http://localhost:1146/upload/做你的爱人.mp3";
    filedown.download(request);
}
复制代码
程序执行到download()方法的时候会自动弹出选择保存文件对话框,根据实际情况选择好保存路径就ok。下面是实现上传和下载的完整代码:

实现上传和下载的完整代码

  <?xml version="1.0" encoding="utf-8"?>
  <mx:application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
      <mx:panel x="49" y="66" width="551" height="164" layout="absolute"
          title="使用filereference上传/下载文件" fontsize="12">
          <mx:hdividedbox x="10" y="10" width="511" height="102">
              <mx:canvas  id="left" backgroundcolor="#d7f4ff" height="100%" width="209">
              <mx:textinput x="4" y="20" id="txtfile" text="{statetext}" width="135"/>
              <mx:button x="147" y="20" label="选择" fontweight="normal" click="{file.browse()}"/>
              <mx:button x="31" y="68" label="上传文件" width="111" fontweight="normal" click="onupload()"/>
             </mx:canvas>
             <mx:canvas id="right" backgroundcolor="#d7f4ff" height="100%" width="282">
                 <mx:label x="6" y="9" text="http://localhost/web/upload/做你的爱人.mp3"/>
                 <mx:button x="10" y="37" label="下载文件" fontweight="normal" click="ondownload()"/>
                 <mx:label x="10" y="74" width="272" id="resultlabel"/>
                 <mx:textinput x="122" y="37" id="downstate"/>
             </mx:canvas>
         </mx:hdividedbox>
         
     </mx:panel>
         <mx:script>
         <![cdata[
             [bindable]
             private var statetext:string = "请选择一个文件上传";
            
             private var file:filereference = new filereference();
             private var filedown:filereference = new filereference();
            
             /**
              * createchildren 比 creationcomplete 事件更早发生
              * */
             protected override function createchildren():void
             {
                 super.createchildren();
                 file.addeventlistener(event.select,onselected);
                 file.addeventlistener(event.complete,oncompleted);
                 file.addeventlistener(progressevent.progress,onprogress);
                 
                 filedown.addeventlistener(event.complete,ondowncompleted);
                 filedown.addeventlistener(progressevent.progress,ondownprogress);
             }
            
//            internal function initapp():void
//            {
//                file.addeventlistener(event.select,onselected);
//                file.addeventlistener(event.complete,oncompleted);
//                file.addeventlistener(progressevent.progress,onprogress);
//            }
            
             internal function onselected(evt:event):void
             {
                 statetext = "选择了文件:" + file.name;
             }
            
             internal function oncompleted(evt:event):void
             {
                 statetext = "上传完毕!";
             }
            
            
             internal function ondowncompleted(evt:event):void
             {
                 var fileref:filereference = evt.currenttarget as filereference;
                 resultlabel.text = "文件名:" + fileref.name + "下载完毕!";
             }
            
             internal function onprogress(evt:progressevent):void
             {
                 statetext = "已上传: " + math.round(100 * evt.bytesloaded / evt.bytestotal) + "%";
                 
             }
            
             internal function ondownprogress(evt:progressevent):void
             {
                 downstate.text = "已下载: " + math.round(100 * evt.bytesloaded / evt.bytestotal) + "%";
             }
            
             /**
              * 调用filereference的实例方法upload()实现文件上传
              * */
             internal function onupload():void
             {
                 if(file.size > 0)
                 {
                     statetext = "正在上传文件:" + file.name;
                 }
                 var request:urlrequest = new urlrequest();
                 request.url=http://localhost/web/uploadhandler.ashx;
                 file.upload(request);
             }
            
             /**
              * 调用filereference类的实例方法download()实现文件下载
              * */
             internal function ondownload():void
             {
                 var request:urlrequest = new urlrequest();
                 request.url="http://localhost/web/upload/做你的爱人.mp3";
                 filedown.download(request);
             }
        ]]>
    </mx:script>
</mx:application>

可能出现的问题:1.可以上传,但是下载报错??
可能是安全沙箱的问题(具体我也不太明白,总之是远程服务端权限问题),可以在服务端根目录添加crossdomain.xml文件
内容:
  <?xml version="1.0" ?>
  <cross-domain-policy>
  <site-control permitted-cross-domain-policies="all" />
  <allow-access-from domain="*" />
  <allow-http-request-headers-from domain="*" headers="*" />
  </cross-domain-policy>
2.英文可以,但是中文报错,或者没有反应??
这样是可以的:
        public function download():void {
                 var url:String=encodeURI("/Download /使用方法.txt");                
          downloadURL = new URLRequest(url);
            file = new FileReference();
            configureListeners(file);
            file.download(downloadURL,"使用方法.txt");//此处为文件名
         }