用delphi和VB实现浏览器中超长文件的上传

用delphi和VB实现浏览器中超长文件的上传
用delphi和VB实现浏览器中超长文件的上传
 

摘 要 本文通过delphi的Tihttp控件,将超大文件分割成几个小文件,通过构造的表单数据流,

            直接发送到接收数据网页,由vb编写的服务器端进行文件接收和还原

一、问题的提出:

本单位在开发课件生成系统时,需要通过浏览器向服务器指定目录传送大的音、视频文件。在微软asp中未提供相应的控件,asp.net虽然提供了form表单中的file控件进行文件上传,但对上传的文件有长度限制,文件长度大于50M上传会失败,而微软基于安全考量,file控件中的文件名在运行期间只读,这样利用微软提供的控件向服务器端上传长度超过50M的文件变为不可行,必须另劈蹊径。

二、解决方案

delphi以其强大的控件集,快速的RAD开发,深得程序开发人员的青睐,其最新控件集Indy,集成了大部分流行的Internet协议,包括TCPUDPDNSICMPFINGERFTPGOPHERHTTPPOP3SMTPTELNETWHOIS,而浏览器的传输协议为http。这样我们可以利用delphi7中的TIHTTP控件,将数据打包后上传到服务器端。基本思路为:开发两部分功能程序,一个为ActiveX控件,嵌入到网页中,负责将客户端本地上传文件分解成n个数据包,每个数据包直接编码成“multipart/form-data”格式的表单信息,依次调用TIhttp控件的post方法向服务器端发送信息。另一个为服务器端的com组件,接受发送过来的原始信息,将数据包拼接还原成文件保存到服务器的指定目录中。

三、技术要点:

    1Delyhi 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.htmupload.aspmyget.dllupfileproj1.ocx文件放置到IIS服务之虚拟目录upfile下(缺省目录为C:"Inetpub"unnroot"upfile);

3.修改upfile.htmcodebase属性(缺省为http://11.68.17.80/upfile/upfileproj1.ocx)中的IP地址为服务器端地址;

4.修改delphi工程文件upfileprojl中的upfilelmpl1文件中的Button2 click事件中的vulstring=’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

你可能感兴趣的:(用delphi和VB实现浏览器中超长文件的上传)