在Flex的应用开发中,同ASP.NET,JSP,PHP等应用一样,都会有上传/下载文件的应用需求,Flex的SDK也为我们提供了专门的类FileRefUdderence实现文件上传/下载 。Flex只是作为一个客户端,要实现上传或下载必须得为其提供一个服务端来接受上传或下载的请求,本文以ASP.NET中的HttpHandler作为文件上传的服务端来完成上传功能。
OK,我们从Flex客户端开始,看看客户端是通过什么方式想服务端发起请求。Flex客户端要完成文件上传下载都是通过FileRefUdderence来实现,首先得定义一个该类型对象实例:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
[Bindable]
2
private
varstateText:String
=
"
请选择一个文件上传
"
;
3//通过调用file对象的方法来完成上传和下载功能
4
private
varfile:FileReference
=
new
FileReference();
上传文件通常涉及到的有选择文件、上传文件以及上传完成这些最基本的处理过程。OK,下面我们就以这三个过程为例来看看Flex是怎么来完成文件的上传功能。首先为这三个功能点分别添加监听事件处理函数,在程序加载时调用:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
internal
functioninitApp():
void
2
{
3
file.addEventListener(Event.SELECT,onSelected);
4
file.addEventListener(Event.COMPLETE,onCompleted);
5
file.addEventListener(ProgressEvent.PROGRESS,onProgress);
6
}
另外我们也可以不用上面这中定义一个函数在程序加载时调用进行初始化操作,应用程序(mxml)的初始化操作又creationComplete方法完成,另外还有一个比它先执行的方法createChildren(),我们可以直接在mxml下重写该方法来实现应用程序的初始化,如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
/*
*
2
*createChildren比creationComplete事件更早发生
3
*
*/
4
protected
override
functioncreateChildren():
void
5
{
6
file.addEventListener(Event.SELECT,onSelected);
7
file.addEventListener(Event.COMPLETE,onCompleted);
8
file.addEventListener(ProgressEvent.PROGRESS,onProgress);
9
}
这三个事件处理函数的详细定义如下(其中的stateText为String的变量,用于显示文件上传状态提示):
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
internal
functiononSelected(evt:Event):
void
2
{
3
stateText
=
"
选择了文件
"
+
file.name;
4
}
5
6
internal
functiononCompleted(evt:Event):
void
7
{
8
stateText
=
"
上传完毕!
"
;
9
}
10
11
internal
functiononProgress(evt:ProgressEvent):
void
12
{
13
stateText
=
"
已上传
"
+
Math.round(
100
*
evt.bytesLoaded
/
evt.bytesTotal)
+
"
%
"
;
14
}
到这里客户端就只差一步了,那就是完成发起上传请求的方法,实际上就是通过URLRequest对象创建一个与服务端的连接,然后直接调用FielReference类的upload()方法就可完成该功能,详细如下代码定义:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
/*
*
2
*调用FileReference的实例方法upload()实现文件上传
3
*
*/
4
internal
functiononUpLoad():
void
5
{
6
if
(file.size
>
0
)
7
{
8
stateText
=
"
正在上传文件:
"
+
file.name;
9
}
10
varrequest:URLRequest
=
new
URLRequest();
11
request.url
=
"
http://localhost/Web/UpLoadHandler.ashx
"
;
12
file.upload(request);
13
}
写好了upload方法,现在就是调用他了,通过按扭的click事件直接调用就可以,另外调用file.browse()方法则实现选择文件的功能,如下mxml代码描述:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
<
mx:TextInput
x
="10"
y
="57"
id
="txtFile"
text
="{stateText}"
width
="229"
/>
2
<
mx:Button
x
="247"
y
="57"
label
="选择"
fontWeight
="normal"
click
="{file.browse()}"
/>
3
<
mx:Button
x
="29"
y
="111"
label
="上传文件"
width
="111"
fontWeight
="normal"
click
="onUpLoad()"
/>
如上便完成了上传文件的Flex客户端开发,通过file.upload()方法,将把选择的文件通过二进制的形式发送到指定的服务端,并自动传递一个叫“fileName”的参数,服务端通过fileName便可以接收到客户端请求上传的文件。最后我们来看看服务端的UpLoadHandler.ashx的详细定义:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
public
class
UpLoadHandler:IHttpHandler
2
{
3
//
文件上传目录
4
private
string
uploadFolder
=
"
UpLoad
"
;
5
6
public
void
ProcessRequest(HttpContextcontext)
7
{
8
context.Response.ContentType
=
"
text/plain
"
;
9
10
HttpFileCollectionfiles
=
context.Request.Files;
11
if
(files.Count
>
0
)
12
{
13
string
path
=
context.Server.MapPath(uploadFolder);
14
HttpPostedFilefile
=
files[
0
];
15
16
if
(file
!=
null
&&
file.ContentLength
>
0
)
17
{
18
string
savePath
=
path
+
"
/
"
+
context.Request.Form[
"
fileName
"
];
19
file.SaveAs(savePath);
20
}
21
}
22
else
23
{
24
context.Response.Write(
"
参数错误
"
);
25
context.Response.End();
26
}
27
}
28
29
public
bool
IsReusable
30
{
31
get
32
{
33
return
false
;
34
}
35
}
36
}
如上一系列的步骤便可完成上传文件的功能,下面便是上传文件示例程序运行截图:
实现了文件上传下面来看看怎么实现文件下载,以上面上传示例中上传的mp3为例,下面我们来看看怎么从服务器(http://localhost/Web/UpLoad/做你的爱人.mp3)上完成文件(做你的爱人.mp3)的下载。
要实现文件下载对服务器端只要保证被下载文件存在就OK,同上传文件一样需要实例化一个FielReference对象的实例,并为其添加相应的事件处理函数:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
private
varfileDown:FileReference
=
new
FileReference();
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
/*
*
2
*createChildren比creationComplete事件更早发生
3
*
*/
4
protected
override
functioncreateChildren():
void
5
{
6
super.createChildren();
7
file.addEventListener(Event.SELECT,onSelected);
8
file.addEventListener(Event.COMPLETE,onCompleted);
9
file.addEventListener(ProgressEvent.PROGRESS,onProgress);
10
//
实现文件下载
11
fileDown.addEventListener(Event.COMPLETE,onDownCompleted);
12
fileDown.addEventListener(ProgressEvent.PROGRESS,onDownProgress);
13
}
如上为实现下载文件的实例fileDown注册了成功下载文件后事件处理函数和下载过程处理函数,下面是两个方法的详细定义:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
internal
functiononDownCompleted(evt:Event):
void
2
{
3
varfileRef:FileReference
=
evt.currentTarget
as
FileReference;
4
resultLabel.text
=
"
文件名:
"
+
fileRef.name
+
"
下载完毕!
"
;
5
}
6
7
internal
functiononDownProgress(evt:ProgressEvent):
void
8
{
9
downState.text
=
"
已下载:
"
+
Math.round(
100
*
evt.bytesLoaded
/
evt.bytesTotal)
+
"
%
"
;
10
}
完成了对象事件的开发,最后便上惩罚下载请求了,直接调用FileReference类所提供的download()方法既可:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->
1
/*
*
2
*调用FileReference类的实例方法download()实现文件下载
3
*
*/
4
internal
functiononDownLoad():
void
5
{
6
varrequest:URLRequest
=
new
URLRequest();
7
request.url
=
"
http://localhost:1146/UpLoad/做你的爱人.mp3
"
;
8
fileDown.download(request);
9
}
程序执行到download()方法的时候会自动弹出选择保存文件对话框,根据实际情况选择好保存路径就OK。下面是实现上传和下载的完整代码:
实现上传和下载的完整代码
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1<?xmlversion="1.0"encoding="utf-8"?>
2<mx:Applicationxmlns:mx="http://www.adobe.com/2006/mxml"layout="absolute">
3<mx:Panelx="49"y="66"width="551"height="164"layout="absolute"
4title="使用FileReference上传/下载文件"fontSize="12">
5<mx:HDividedBoxx="10"y="10"width="511"height="102">
6<mx:Canvasid="left"backgroundColor="#D7F4FF"height="100%"width="209">
7<mx:TextInputx="4"y="20"id="txtFile"text="{stateText}"width="135"/>
8<mx:Buttonx="147"y="20"label="选择"fontWeight="normal"click="{file.browse()}"/>
9<mx:Buttonx="31"y="68"label="上传文件"width="111"fontWeight="normal"click="onUpLoad()"/>
10</mx:Canvas>
11<mx:Canvasid="right"backgroundColor="#D7F4FF"height="100%"width="282">
12<mx:Labelx="6"y="9"text="http://localhost/Web/UpLoad/做你的爱人.mp3"/>
13<mx:Buttonx="10"y="37"label="下载文件"fontWeight="normal"click="onDownLoad()"/>
14<mx:Labelx="10"y="74"width="272"id="resultLabel"/>
15<mx:TextInputx="122"y="37"id="downState"/>
16</mx:Canvas>
17</mx:HDividedBox>
18
19</mx:Panel>
20<mx:Script>
21<![CDATA[
22[Bindable]
23privatevarstateText:String="请选择一个文件上传";
24
25privatevarfile:FileReference=newFileReference();
26privatevarfileDown:FileReference=newFileReference();
27
28/**
29*createChildren比creationComplete事件更早发生
30**/
31protectedoverridefunctioncreateChildren():void
32{
33super.createChildren();
34file.addEventListener(Event.SELECT,onSelected);
35file.addEventListener(Event.COMPLETE,onCompleted);
36file.addEventListener(ProgressEvent.PROGRESS,onProgress);
37
38fileDown.addEventListener(Event.COMPLETE,onDownCompleted);
39fileDown.addEventListener(ProgressEvent.PROGRESS,onDownProgress);
40}
41
42//internalfunctioninitApp():void
43//{
44//file.addEventListener(Event.SELECT,onSelected);
45//file.addEventListener(Event.COMPLETE,onCompleted);
46//file.addEventListener(ProgressEvent.PROGRESS,onProgress);
47//}
48
49internalfunctiononSelected(evt:Event):void
50{
51stateText="选择了文件:"+file.name;
52}
53
54internalfunctiononCompleted(evt:Event):void
55{
56stateText="上传完毕!";
57}
58
59
60internalfunctiononDownCompleted(evt:Event):void
61{
62varfileRef:FileReference=evt.currentTargetasFileReference;
63resultLabel.text="文件名:"+fileRef.name+"下载完毕!";
64}
65
66internalfunctiononProgress(evt:ProgressEvent):void
67{
68stateText="已上传:"+Math.round(100*evt.bytesLoaded/evt.bytesTotal)+"%";
69
70}
71
72internalfunctiononDownProgress(evt:ProgressEvent):void
73{
74downState.text="已下载:"+Math.round(100*evt.bytesLoaded/evt.bytesTotal)+"%";
75}
76
77/**
78*调用FileReference的实例方法upload()实现文件上传
79**/
80internalfunctiononUpLoad():void
81{
82if(file.size>0)
83{
84stateText="正在上传文件:"+file.name;
85}
86varrequest:URLRequest=newURLRequest();
87request.url=http://localhost/Web/UpLoadHandler.ashx;
88file.upload(request);
89}
90
91/**
92*调用FileReference类的实例方法download()实现文件下载
93**/
94internalfunctiononDownLoad():void
95{
96varrequest:URLRequest=newURLRequest();
97request.url="http://localhost/Web/UpLoad/做你的爱人.mp3";
98fileDown.download(request);
99}
100]]>
101</mx:Script>
102</mx:Application>
103
程序运行截图:
本文首发于博客园,地址:http://www.cnblogs.com/beniao/archive/2009/01/18/1377668.html