摘 要 本文通过delphi的Tihttp控件,将超大文件分割成几个小文件,通过构造的表单数据流,
直接发送到接收数据网页,由vb编写的服务器端进行文件接收和还原
一、问题的提出:
本单位在开发课件生成系统时,需要通过浏览器向服务器指定目录传送大的音、视频文件。在微软asp中未提供相应的控件,asp.net虽然提供了form表单中的file控件进行文件上传,但对上传的文件有长度限制,文件长度大于50M上传会失败,而微软基于安全考量,file控件中的文件名在运行期间只读,这样利用微软提供的控件向服务器端上传长度超过50M的文件变为不可行,必须另劈蹊径。
二、解决方案
delphi以其强大的控件集,快速的RAD开发,深得程序开发人员的青睐,其最新控件集Indy,集成了大部分流行的Internet协议,包括TCP、UDP、DNS、ICMP、FINGER、FTP、GOPHER、HTTP、POP3、SMTP、TELNET、WHOIS,而浏览器的传输协议为http。这样我们可以利用delphi7中的TIHTTP控件,将数据打包后上传到服务器端。基本思路为:开发两部分功能程序,一个为ActiveX控件,嵌入到网页中,负责将客户端本地上传文件分解成n个数据包,每个数据包直接编码成“multipart/form-data”格式的表单信息,依次调用TIhttp控件的post方法向服务器端发送信息。另一个为服务器端的com组件,接受发送过来的原始信息,将数据包拼接还原成文件保存到服务器的指定目录中。
三、技术要点:
1.Delyhi 7开发Active X控件要点:选择新建项目→Active x标签→Active Form→填入控件名可快速搭建一个Acfire X控件架构,产生一个表单和一个框架代码文件。
2.上传Active x控件设计要点:①表单控件中放置一个编辑控件、三个命令按钮、一个进度条控件、一个文本标签控件、一个文件对话框控件。编辑控件用来放置上传文件名。一个浏览按钮打开文件选择对话框,选择上传文件;进度条控件显示上传文件进度;文本标签显示上传文件百分比,取消按钮可中断文件上传。
②项目包含两个代码文件,其中一个文件用来将上传文件拆分成小数据包。其关键代码如下:
for y:=0 to filenum do
begin
if y=0 then //第一个包
begin
if y <> filenum then
begin
for i:=1 to basenum do
begin
read(f,ch);
tempf:=chr(ch);
temp:=temp+tempf;
application.ProcessMessages;
end;
vflag:=postdata(vurl,vfilename,temp,'0');
end
else
begin
j:=0;
while not eof(f) do
begin
read(f,ch);
tempf:=chr(ch);
temp:=temp+tempf;
j:=j+1;
application.ProcessMessages;
vflag:=postdata(vurl,vfilename,temp,'-2');
end;
end
else if y<> filenum then //中间包
begin
for i:=1 to basenum do
begin
read(f,ch);
tempf:=chr(ch);
temp:=temp+tempf;
application.ProcessMessages;
end;
vflag:=postdata(vurl,vfilename,temp,'1');
end
else //最后一个包
begin
j:=0;
while not eof(f) do
begin
read(f,ch);
tempf:=chr(ch);
temp:=temp+tempf;
j:=j+1;
application.ProcessMessages;
end;
vflag:=postdata(vurl,vfilename,temp,'-1');
end;
end;
end;
③另一个文件用来将小数据包按照http格式封装成二进制文件上传数据流发送到指定的接收页面(URL),数据流除必要的头信息,包含两个表单城,一个数据块,其中一个表单域用来传递文件标记,用来区分本数据包是第一个包,中间包还是最后一个包,另一个表单域传递上传文件名,其关键代码如下:
try
filedata.Seek(0,sofrombeginning);
tempstring:='';
tempstring:=tempstring+'------------------------------7cf87224d2020a'+
newline;
tempstring:=tempstring+'Content-Disposition: form-data;name="vflag"'+newline;
tempstring:=tempstring+''+newline;
tempstring:=tempstring+vflag+newline;
tempstring:=tempstring+''+newline;
tempstring:=tempstring+''+newline;
tempstring:=tempstring+'Content-Disposition: form-data; name="editfilename"; filename="'+infile+'"'+newline;
tempstring:=tempstring+'Content-Type: application/octet-stream'+newline;
tempstring:=tempstring+''+newline;
fillchar(temparray,sizeof(temparray),#0);
strpcopy(temparray,tempstring);
request.Write(temparray,length(tempstring));
request.seek(0,sofromend);
request.CopyFrom(filedata,filedata.size);
tempstring:='';
tempstring:=tempstring+''+newline;
tempstring:=tempstring+'------------------------------7cf87224d2020a--'
+newline;
fillchar(temparray,sizeof(temparray),#0);
strpcopy(temparray,tempstring);
request.write(temparray,length(tempstring));
try
http.Post(url,request,response);
if pos('成功',response.datastring)<>0 then
flag:=1
end.
End.
④本ActiveX控件特色:可以实时显示上传进度,并能随时中断文件的上传,上传页面画面如图所示,可不能随时中断文件上传,即应用程序能随时从循环语句中跳出,在循环语句中使用了ayydicdition Process Messages语句,该语句用来监听和处理系统消息这样就有效避免了文件上传时,不能进行系统的其它操作。
3.用VB6.0开发服务器端接收文件的Activeex dll,主要利用VB6.0强大的网页操作功能,引用库文件microsoft Active sever Page object library。其中包含有asp对象Asp library request。创建一个接收函数load,使用request对象读取上传给接收页面的二进制数据流,分离出上传标志、上传文件名以及文件内容,根据上传标志将分段传送来的文件内容拼接成一个完整的文件,保存到指定目录。
四、几点说明:
1.本程序在操作系统为Win98 Win2000的客户端机器,IIS服务器端为Win 2000的环境下调试通过;
2.将upfile.htm,upload.asp,myget.dll,upfileproj1.ocx文件放置到IIS服务之虚拟目录upfile下(缺省目录为C:"Inetpub"unnroot"upfile);
3.修改upfile.htm中codebase属性(缺省为http://11.68.17.80/upfile/upfileproj1.ocx)中的IP地址为服务器端地址;
4.修改delphi工程文件upfileprojl中的upfilelmpl1文件中的Button2 click事件中的vul:string=’http://11.68.17.80/upfile/upload.asp’一行数据,将其中的IP地址转接为服务器端地址,重新编译后将upfrleprojl.ocx放置到虚拟目录下;
5.上传文件在服务器端的默认保存目录为c:"temp;
6.须手工注册myget.dll,命令语句为regsvr32 C:"inetpub"wwwroot"upfile"myget.dll
7.览器中敲击网站地址执行,缺省地址为http://11.68.17.80/upfile/upfile.htm。 |