知识大全 用Delphi 6开发ASP上传组件详解

Posted 文件

篇首语:年轻不是用来放纵的理由而是奋斗的资本!本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 用Delphi 6开发ASP上传组件详解相关的知识,希望对你有一定的参考价值。

用Delphi 6开发ASP上传组件详解  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  文件上传是WEB开发中经常要用到的功能 但ASP本身和内置的组件都不支持文件上传功能 网上流传的一些第三方组件虽然能够解决这个问题 但大多是要收费的 更别说Open Source了 本文将详细剖析WEB文件上传的原理 以及一步步指导读者如何用Delphi 开发一个ASP上传组件

  源码和demo我已经发布在个人主页上// wushuang net.

  一 Html文件分析  首先我们来看一个文件源码 文件名是test 功能是提供用户上传的界面

<> <body> <center>    <form name= mainForm enctype= multipart/form data action= test asp method=post>     <input type=file name=mefile><br>      <input type=hidden name=a value= fdsaf >     <input type=hidden name=a value= fdsaf >     <input type=hidden name=a value= fdsaf >     <input type=hidden name=a value= fsdfsdsaf >     <input type=hidden name=a value= 这个是这个 >     <input type=text name=a value= fdsaf >   <input type=submit name=ok value= OK >    </form> </center> </body> </>

  这个文件里包含了一个名为mainForm的form 以及随手写的一些input域 注意这个form和一般的form有两个不同的地方 一是它有一个type=file的域 没有value 用浏览器打开这个文件时 这个域会表现为一个右侧有 浏览 字样的文件输入框 用户可以通过它来选择本地硬盘上的文件 二是form有一个特殊的属性 enctype= multipart/form data 这个属性告诉浏览器要上传二进制文件 并进行相应编码   这种编码会产生什么样的表单信息呢?让我们来看看test asp 也就是接受表单的asp文件的源码 它非常简单

<% formsize=request totalbytes    获得表单原始信息的长度formdata=request binaryread(formsize)    读取表单原始信息

response binarywrite formdata   返回表单原始信息%>

  如读者在注释中了解的 这段代码的功能是将表单的原始信息返回 让我们来看看它的运行效果 将这两个文件置于web目录下 访问test 在文件输入框中 选择一个文件(我选了一个jpg图片 不过最大不要太大) 提交 然后可以看到这样一堆乱七八糟的信息

d e Content Disposition: form data; name= mefile ; filename= C:\\Documents and Settings\\aaa\\My Documents\\My Pictures\\zzjh jpg Content Type: image/pjpeg (作者注 以下为乱码) d e Content Disposition: form data; name= a fdsaf d e Content Disposition: form data; name= a fdsaf d e Content Disposition: form data; name= a fdsaf d e Content Disposition: form data; name= a fsdfsdsaf d e Content Disposition: form data; name= a 这个是这个 d e Content Disposition: form data; name= a fdsaf d e Content Disposition: form data; name= ok OK d e

  这就是用 multipart/form data 方式编码的表单原始信息 其中那一段看起来是乱码的部分 就是jpg图片的编码     分析一下这段信息的格式   

d e 这是各个域之间的分隔符 Content Disposition: form data; 说明这是表单中的域 name= mefile ; 域的名称 filename= C:\\Documents and Settings\\aaa\\My Documents\\My Pictures\\zzjh jpg 上传文件在本地硬盘上的名称 Content Type: image/pjpeg 文件类型 后面是文件本身的数据

  其它各个域的信息也可以以此类推   众所周知 在ASP中 使用request对象 可以访问用户提交表单的各个域 因为request对象会对原始的表单信息进行解析 提取出表单中每个域的值 但是 request并不能解析这 multipart/form data 格式的表单信息 这就是ASP不能直接支持文件上传的原因所在 读者可以试试 在test asp中 用request( mefile )这样的格式 是不能读取到正确的信息的     问题的症结已经找到 解决的思路也很简单 用Delphi开发一个组件 接受这种原始表单信息 将各个域一一提取出来 返回给asp文件 也就是完成request对象没有完成的功能

  二 用Delphi开发组件

  Delphi 对开发ASP组件提供了极好的支持 大大简化了我们的开发过程   启动Delphi 选择File New Other ActiveX ActiveX Library 这样就建立了一个ActiveX库 将此Library改名为myobj 存盘 选择File New Other ActiveX Active Server Object 在CoClassname中填入upfile 确定 这时会跳出一个标题为myobj tlb的对话框 这是Delphi特有的以可视化方式编辑接口的功能 用Delphi开发过的读者应该比较熟悉   在myobj下的名为Iupfile的Interface下 添加 个属性和一个方法 如果不懂得如何操作 请参见Delphi参考书的相关部分 按F 可以看到生成的相应的myobj_tlb pas文件 其中的Iupfile接口应该是这个样子

  Iupfile = interface(IDispatch)    [ C D EB A A E AE B ]    procedure OnStartPage(const AScriptingContext: IUnknown); safecall;    procedure OnEndPage; safecall;    function  Get_Form(Formname: OleVariant): OleVariant; safecall;    function  Get_FileName: OleVariant; safecall;    function  Get_FileSize: Integer; safecall;    procedure FileSaveAs(FileName: OleVariant); safecall;    function  Get_FileData: OleVariant; safecall;    function  Get_FileType: OleVariant; safecall;    property Form[Formname: OleVariant]: OleVariant read Get_Form;    property FileName: OleVariant read Get_FileName;    property FileSize: Integer read Get_FileSize;    property FileData: OleVariant read Get_FileData;    property FileType: OleVariant read Get_FileType;  end;

  其中的OnStartPage方法和OnEndPage方法是Delphi默认生成的 其它的是手动加入的   切换到unit pas(也是Delphi自动生成的) 改名为upfile pas存盘 可以看到存在一个Tupfile类的声明 它是继承自TASPObject类和Iupfile接口的 Delphi 已经自动生成了相应的代码 接下来的任务就是实现这个接口   除了完成Iupfile接口中的属性和方法之后 还需要补充一些东西 以便完成我们的任务 最终的Tupfile类的声明如下

  Tupfile = class(TASPObject Iupfile)  public  protected    procedure OnEndPage; safecall;  //页面开始     procedure OnStartPage(const AScriptingContext: IUnknown); safecall;  //页面结束    procedure FileSaveAs(Filename: OleVariant); safecall;  //保存文件    function Get_Form(Formname: OleVariant): OleVariant; safecall;  //    function Get_FileName: OleVariant; safecall;      function Get_FileSize: Integer; safecall;    function Get_FileData: OleVariant; safecall;    function Get_FileType: OleVariant; safecall;  private    FContentData:string;    FFileData FFileName FFileType:string;    FFormInfo:TStringList;    function instr(str str :string;startpos:integer):integer;    procedure AnalyFormData(content:string);  end;

  下面我们来一一分析这些成员的具体实现

procedure Tupfile OnStartPage(const AScriptingContext: IUnknown);var  AOleVariant : OleVariant;  tmpvar : OleVariant;  contentlength : integer;  i DeliCount pos pos lastpos : integer;  FDelimeter : string;begin  inherited OnStartPage(AScriptingContext);  FFormInfo := TStringList Create;

  contentlength := Request TotalBytes;  AOleVariant := contentlength;  tmpvar := Request BinaryRead(AOleVariant);  for i := to contentlength do  begin    FContentData := FContentData + chr(byte(tmpvar[i]));  end;

  pos := pos(# # FContentData);  FDelimeter := copy(FContentData pos + );  DeliCount := length(FDelimeter);  lastpos := ;

  pos := ;  while pos >=pos do  begin    pos := instr(FDelimeter FContentData lastpos);    if pos = then Break;    pos := pos + DeliCount;    pos := instr(FDelimeter FContentData pos ) ;    AnalyFormData(copy(FContentData pos pos pos ));    lastpos := pos ;  end;end;

  前面说过 OnStartPage方法是Delphi自动生成的 在装载页面时发生 在这个方法中 我们完成一些初始化的任务 读取表单的原始数据 解析表单中的域 并存入相应的属性中 以备调用   由于Delphi已经对ASP中的对象进行了很好的封装 所以即使在Delphi环境下 也可以方便地调用它们 就象在ASP中一样 例如Request TotalBytes 首先将原始表单数据读入到一个OleViarians类型的tmpvar中 然后通过一个循环 将它转换为Delphi中的string格式 并存放在FContentData中   接下来 通过查找换行符 解析出分隔符的内容和长度 然后在一个循环中 用AnalyFormData成员函数一一解析出每个域 初始化工作就这样完成了

  再看AnalyFormData函数的实现

procedure Tupfile AnalyFormData(content: string);var  pos pos :integer;  FormName FormValue:string;  isFile:boolean;begin  isFile := false;  pos := instr( name= content )+ ;  pos := instr( content pos );  FormName := copy(content pos pos pos );

  //检查是否文件  pos := instr( filename= content pos + );  if pos <> then  begin    isFile := true;    pos := pos + ;    pos := instr( content pos );    FFilename := copy(content pos pos pos );  end;

  pos := instr(# # # # content pos + )+ ;  FormValue := copy(content pos length(content) pos );

  if isfile then  begin    FFileData := FormValue;    //查找文件类型信息    pos := instr( Content Type: content pos + );    if pos <> then    begin      pos := pos + ;      FFileType := copy(content pos pos pos );    end;  end  else  begin  FFormInfo add(FormName+ = +FormValue);  end;end;

  如注释中所表达的 AnalyFormData提取原始数据中的域 如果是域是文件类型 则将文件类型和文件数据分别放入FFileType和FFileData中 如果是其它类型 则将名称和值放入一个TStringlist类型的FFormInfo中 FFormInfo中维护着除文件类型外的所有域的信息 以 名称=值 的格式存放   function Tupfile Get_Form(Formname: OleVariant): OleVariant;begin    Result := FFormInfo Values[Formname];end;

  这个函数返回域的值 只需要简单地调用FFormInfo的values方法 就可以得到相应的值 这是在Tstringlist类内部实现的

function Tupfile Get_FileName: OleVariant;begin  Result := ExtractFileName(FFileName);end;

function Tupfile Get_FileSize: Integer;begin  Result := length(FFileData);end;

function Tupfile Get_FileData: OleVariant;var  i:integer;begin  Result := VarArrayCreate( [ length(FFileData)] varByte );  for i := to length(FFileData) do  begin    Result[i] := Byte(FFileData[i+ ]);  end;end;

  这三个函数分别返回文件的名称 大小 数据 要注意的是 在返回文件数据时 必须进行相应的转换 将Delphi中的string类型转换为OleVariant类型   procedure Tupfile FileSaveAs(Filename: OleVariant);var  fsout:TFileStream;  i:integer;  afile:file of byte;begin  fsout := TFileStream Create(Filename fmcreate);  for i := to length(FFileData) do  begin    fsout Write(Byte(FFileData[i]) )  end;  fsout Free;end;

  这个方法将文件保存到服务器上的磁盘

  编译myobj这个project 得到一个myobj dll文件 开发工作就此完成

  三 使用ASP上传组件    在命令行下 输入 regsvr myobj dll 弹出一个对话框 告诉你组件已经注册 如果找不到regsvr exe这个文件 它在windows\\system 或winnt\\system 目录下   将本文开头提到的test asp文件修改为如下内容

<% 建立对象 Set upfile = Server CreateObject( myobj upfile )

获得表单对象response write upfile form( a )& <br> response write upfile form( a )& <br> response write upfile form( a )& <br> response write upfile form( a )& <br> response write upfile form( a )& <br> response write upfile form( a )& <br>

获得文件大小response write 文件字节数 &upfile filesize& <br> 获得文件类型response write 文件类型 &upfile filetype& <br>

获得文件名 保存文件upfile filesaveas(Server MapPath( )+upfile filename)

set upfile = nothing%>

cha138/Article/program/Delphi/201311/24952

相关参考

知识大全 asp利用文件上传组件upload

  我们是利用upload文件上传组件进行文件上传哦  <%ServerScriptTimeOut=%><!#includefile="connasp"><!#inclu

知识大全 Asp.NET大文件上传组件---提取文件内容

Asp.NET大文件上传组件---提取文件内容  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  为

知识大全 asp限制上传文件大小实例

  一款利用asp文件上传组件把文件上传到服务器之前进行判断文件大小否超过指定大小了本实例讲的是upload_xsoft文件上传组件哦filefilesize>就可以限制文件为多少klishix

知识大全 Delphi开发WEB应用程序打印组件[3]

Delphi开发WEB应用程序打印组件[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ()

知识大全 Delphi开发WEB应用程序打印组件[2]

Delphi开发WEB应用程序打印组件[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  四调

知识大全 Delphi开发WEB应用程序打印组件[1]

Delphi开发WEB应用程序打印组件[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  近些

知识大全 Asp.NET大文件上传开发总结(一)

Asp.NET大文件上传开发总结(一)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  以前开发过

知识大全 Asp.NET大文件上传开发总结集合

Asp.NET大文件上传开发总结集合  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  以前开发过一

知识大全 Asp.NET大文件上传开发总结(二)

Asp.NET大文件上传开发总结(二)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  为了提供文

知识大全 ASP.NET项目开发指南:网络书店数据库操作组件

ASP.NET项目开发指南:网络书店数据库操作组件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!