GONE WITH THE WIND

          --tomorrow is another day

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            30 隨筆 :: 19 文章 :: 0 評論 :: 0 Trackbacks
          用delphi和VB實現(xiàn)瀏覽器中超長文件的上傳
           

          摘 要 本文通過delphi的Tihttp控件,將超大文件分割成幾個小文件,通過構(gòu)造的表單數(shù)據(jù)流,

                      直接發(fā)送到接收數(shù)據(jù)網(wǎng)頁,由vb編寫的服務(wù)器端進(jìn)行文件接收和還原

          一、問題的提出:

          本單位在開發(fā)課件生成系統(tǒng)時,需要通過瀏覽器向服務(wù)器指定目錄傳送大的音、視頻文件。在微軟asp中未提供相應(yīng)的控件,asp.net雖然提供了form表單中的file控件進(jìn)行文件上傳,但對上傳的文件有長度限制,文件長度大于50M上傳會失敗,而微軟基于安全考量,file控件中的文件名在運行期間只讀,這樣利用微軟提供的控件向服務(wù)器端上傳長度超過50M的文件變?yōu)椴豢尚校仨毩砼鑿健?/span>

          二、解決方案

          delphi以其強大的控件集,快速的RAD開發(fā),深得程序開發(fā)人員的青睞,其最新控件集Indy,集成了大部分流行的Internet協(xié)議,包括TCPUDPDNSICMPFINGERFTPGOPHERHTTPPOP3SMTPTELNETWHOIS,而瀏覽器的傳輸協(xié)議為http。這樣我們可以利用delphi7中的TIHTTP控件,將數(shù)據(jù)打包后上傳到服務(wù)器端。基本思路為:開發(fā)兩部分功能程序,一個為ActiveX控件,嵌入到網(wǎng)頁中,負(fù)責(zé)將客戶端本地上傳文件分解成n個數(shù)據(jù)包,每個數(shù)據(jù)包直接編碼成“multipart/form-data”格式的表單信息,依次調(diào)用TIhttp控件的post方法向服務(wù)器端發(fā)送信息。另一個為服務(wù)器端的com組件,接受發(fā)送過來的原始信息,將數(shù)據(jù)包拼接還原成文件保存到服務(wù)器的指定目錄中。

          三、技術(shù)要點:

              1Delyhi 7開發(fā)Active X控件要點:選擇新建項目→Active x標(biāo)簽→Active Form→填入控件名可快速搭建一個Acfire X控件架構(gòu),產(chǎn)生一個表單和一個框架代碼文件。

          2.上傳Active x控件設(shè)計要點:①表單控件中放置一個編輯控件、三個命令按鈕、一個進(jìn)度條控件、一個文本標(biāo)簽控件、一個文件對話框控件。編輯控件用來放置上傳文件名。一個瀏覽按鈕打開文件選擇對話框,選擇上傳文件;進(jìn)度條控件顯示上傳文件進(jìn)度;文本標(biāo)簽顯示上傳文件百分比,取消按鈕可中斷文件上傳。

          ②項目包含兩個代碼文件,其中一個文件用來將上傳文件拆分成小數(shù)據(jù)包。其關(guān)鍵代碼如下:

              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;

          ③另一個文件用來將小數(shù)據(jù)包按照http格式封裝成二進(jìn)制文件上傳數(shù)據(jù)流發(fā)送到指定的接收頁面(URL),數(shù)據(jù)流除必要的頭信息,包含兩個表單城,一個數(shù)據(jù)塊,其中一個表單域用來傳遞文件標(biāo)記,用來區(qū)分本數(shù)據(jù)包是第一個包,中間包還是最后一個包,另一個表單域傳遞上傳文件名,其關(guān)鍵代碼如下:

             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控件特色:可以實時顯示上傳進(jìn)度,并能隨時中斷文件的上傳,上傳頁面畫面如圖所示,可不能隨時中斷文件上傳,即應(yīng)用程序能隨時從循環(huán)語句中跳出,在循環(huán)語句中使用了ayydicdition Process Messages語句,該語句用來監(jiān)聽和處理系統(tǒng)消息這樣就有效避免了文件上傳時,不能進(jìn)行系統(tǒng)的其它操作。

          3.用VB6.0開發(fā)服務(wù)器端接收文件的Activeex dll,主要利用VB6.0強大的網(wǎng)頁操作功能,引用庫文件microsoft Active sever Page object library。其中包含有asp對象Asp library request。創(chuàng)建一個接收函數(shù)load,使用request對象讀取上傳給接收頁面的二進(jìn)制數(shù)據(jù)流,分離出上傳標(biāo)志、上傳文件名以及文件內(nèi)容,根據(jù)上傳標(biāo)志將分段傳送來的文件內(nèi)容拼接成一個完整的文件,保存到指定目錄。

          四、幾點說明

              1.本程序在操作系統(tǒng)為Win98 Win2000的客戶端機器,IIS服務(wù)器端為Win 2000的環(huán)境下調(diào)試通過;

          2.將upfile.htmupload.aspmyget.dllupfileproj1.ocx文件放置到IIS服務(wù)之虛擬目錄upfile下(缺省目錄為C:"Inetpub"unnroot"upfile);

          3.修改upfile.htmcodebase屬性(缺省為http://11.68.17.80/upfile/upfileproj1.ocx)中的IP地址為服務(wù)器端地址;

          4.修改delphi工程文件upfileprojl中的upfilelmpl1文件中的Button2 click事件中的vulstring=’http://11.68.17.80/upfile/upload.asp’一行數(shù)據(jù),將其中的IP地址轉(zhuǎn)接為服務(wù)器端地址,重新編譯后將upfrleprojl.ocx放置到虛擬目錄下;

          5.上傳文件在服務(wù)器端的默認(rèn)保存目錄為c:"temp;

          6.須手工注冊myget.dll,命令語句為regsvr32  C:"inetpub"wwwroot"upfile"myget.dll

          7.覽器中敲擊網(wǎng)站地址執(zhí)行,缺省地址為http://11.68.17.80/upfile/upfile.htm
          posted on 2009-03-27 08:48 張永耀 閱讀(490) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 定兴县| 海门市| 瓮安县| 买车| 津市市| 拜城县| 安图县| 曲阳县| 大名县| 裕民县| 仁怀市| 安多县| 余干县| 高唐县| 枣强县| 开远市| 德化县| 大荔县| 汤阴县| 贵南县| 聊城市| 子洲县| 朝阳县| 铜梁县| 墨玉县| 东至县| 揭西县| 子长县| 湾仔区| 宁武县| 桦甸市| 东丰县| 吴江市| 徐州市| 东海县| 阿图什市| 通道| 马公市| 德昌县| 嘉兴市| 霍林郭勒市|