敬业的IT人 >> 编程开发 >> Delphi >> 用DELPHI为ASP开发文件上载组件

用DELPHI为ASP开发文件上载组件

敬业的IT人 互联网 佚名 2008-1-4 16:49:07
ASP(Active Server Page)是微软公司的产品,由于它编程很容易上手,能快速开发功能强大的动态网站,现在很多网站(特别是Intranet/Extranet内部网)采用了NT+IIS+ASP的模式,使得ASP成为目前较为流行的网站开发脚本语言。在WEB服务中,文件上载服务是一个很常见的功能,而WIN9X下的PWS没有提供相关组件;NT下的IIS提供了一个Post Acceptor组件,但由于它要检查用户的WWW访问权限而变得不太好用;也可以从Internet上下载有关组件,但这些大多都是商业组件,用于下载的是试用版,在使用时间或功能上都有限制。由于ASP可以调用标准的OLE/COM组件,我们可以用VB/VC/DELPHI等高级编程工具根据我们自己的要求来定制自己的ASP文件上载组件,满足自己的应用系统要求。

下面将讨论用DELPHI为ASP开发文件上载组件的原理和具体实现过程。


一、文件上载的实现原理

基于Web方式数据上传,要遵从RFC1867标准,上载的文件数据也不例外。如用下面HTML页面文件(delphiup.htm)选择上载文件:

<!-- DelphiUp.htm:文件上载界面 -->

<html><head><title>文件上载</title></head><body>

用DELPHI编写的文件上载组件实现文件上载

<form NAME="UploadForm" ACTION="delphiup.asp" METHOD="POST" ENCTYPE="multipart/form-data">

<p>文件另存为:<input TYPE=text NAME="SaveAs">

<p>请要选择上载的文件:<input TYPE=file NAME="FileData">

<input type="submit" name="b1" value="确认上载"> </p>

</form>

</body></html>

当客户端选择了一个文件(如Test.TXT,其内容为“这里是一个用于上载的文件的内容。”)并按

“确认上载”按钮提交数据后,服务器端程序收到的数据将具有如下形式:

-----------------------------7cf1d6c47c#13#10

Content-Disposition: form-data; name="SaveAs"#13#10#13#10

NewFileName#13#10

-----------------------------7cf1d6c47c#13#10

Content-Disposition: form-data; name="FileData"; filename="D: est.txt"

Content-Type: text/plain#13#10#13#10

这里是一个用于上载的文件的内容。#13#10

-----------------------------7cf1d6c47c#13#10

Content-Disposition: form-data; name="b1"#13#10#13#10

确认上载#13#10

-----------------------------7cf1d6c47c--

其中,“-----------------------------7cf1d6c47c”是分界符,用于分隔表单(Form)中的各个域;

#13#10是回车换行符的DELPHI表示。我们可以这样认为,每个表单域的信息描述,都是以分界符加一对回车换行符#13#10开始;表单域名以“name="”开始,以“"”为结束;表单域值以两对回车换行符#13#10#13#10开始,以一对回车换行符#13#10#加分界符结束;文件名称以“filename="”开始,以“"”为结束。有了这些标志,我们就可以获取表单域的名称和值以及要上载的文件的名称,从而实现文件数据的读取和存储了。


二、文件上载的实现过程

在理解上面提到的数据格式后,自己动手编写一个文件上载组件对我们来说已经不是困难了。


(一)开始建立一个ASP组件的工程

如果您对用DELPHI开发OLE Automation Server的步骤不太熟悉的话,请参见《电子与电脑》1999年第06期的一篇文章《用DELPHI开发用于ASP的OLE Automation Server 》。

这里只简要介绍一下操作步骤。

1、建立ActiveX Library工程

在DELPHI中选择菜单File=》New...,在“New Item”对话框的ActiveX选项卡中选择“ActiveX Library”,DELPHI会自动创建一个DLL工程Project1。

2、建立Automation组件

在DELPHI中选择菜单File=》New...,在“New Item”对话框的ActiveX选项卡中选择“Automation Object”;然后在“Automation Object Wizard”对话框中输入Class Name(如“UploadFile”),Instancing选择“Multiple Instance”即可,单击“OK”后DELPHI会自动创建一个TLB(Type Library)文件Project1_TLB.PAS和一个PAS(Unit)文件Unit1.PAS。在Type Library设计窗口中,将Project1改名为MyUpload,则该文件上载组件的OLE注册码为“MyUpload.UploadFile”。

3、引入ASP类型库

为了使用ASP的五个内建对象(Request、Response、Server、Application、Session),需要引入ASP类型库。我们主要利用Request对象读取从客户端传递到服务器端的数据。

在Project菜单中选择“Import Type Library”,在“Import Type Library”对话框的“Type Libraries”列表选择“Microsoft Active Server Pages Object Library(Version 2.0)”(如果没有这个选项,请确定您的计算机上安装了IIS3以上或PWS4以上并且ASP.DLL已正确注册),DELPHI会自动创建一个TLB文件ASPTypeLibrary_TLB.PAS,其中有我们需要的ASP对象类型声明。

4、定义OnStartPage、OnEndPage过程

当在ASP页面上用Server.CreateObject创建一个OLE对象实例时,WEB服务器会调用其方法OnStartPage,将ASP应用环境信息传递给该对象,我们可以在该过程中获取客户端信息;当在ASP页面中释放一个OLE对象实例时,WEB服务器会调用其方法OnEndPage,我们可以在该过程中进行释放内存等结束操作。在我们这个组件中,我们要用到其OnStartPage方法。

OnStartPage方法应该在Unit1.PAS中定义,OnStartPage的函数原型为:

procedure的形式存储

strTemp := 'filename="';//文件名称在“filename="”之后

longPos := pos( strTemp, ContentData );//获取“filename="”位置

if longPos <= 0 then

begin

FFileName := ';

FFileDataStart := -1;

FFileDataEnd := -2;

exit;

end;

//获取下个双引号“"”之前的内容,即带源路径的文件名称

longPos := longPos length( strTemp );

strTemp := ';

for longIndex := longPos to FContentLength - 1 do

if ContentData[ longIndex ] <> '"' then

strTemp := strTemp ContentData[ longIndex ]

else break;

FFileName := strTemp;


4、获取文件数据的在请求信息内容中的开始、结束位置

//文件数据开始位置在文件名称后的第一个#13#10#13#10之后

delete( ContentData, 1, longIndex );

strTemp := #13#10#13#10;

FFileDataStart := longIndex pos(strTemp, ContentData) length(strTemp) - 1;


//文件数据结束位置在下一个#13#10和分界符之前

//由于文件数据可能包含非法字符,不能再用字符串定位函数POS

//查找下一个分界符的位置

FFileDataEnd := FFileDataStart;

intDelimterLength := length( FDelimeter );

FindEndOfFileData := false;

while FFileDataEnd <= FContentLength - intDelimterLength do

begin

FindEndOfFileData := true;

for ALongInt := 0 to intDelimterLength - 1 do

if Byte( FDelimeter[ ALongInt 1 ] ) <>

FContentData[ FFileDataEnd ALongInt ] then

begin

FindEndOfFileData := false;

break;

end;

if FindEndOfFileData then break;

FFileDataEnd := FFileDataEnd 1;

end;

if not FindEndOfFileData then FFileDataEnd := FFileDataStart - 1//未找到分界符

else FFileDataEnd := FFileDataEnd - 3;//分界符,向前跳过#13#10

end;


(三)向ASP程序传递信息

在进行了(二)的操作之后,我们的上载组件可以根据ASP程序的要求向其传递数据了。目前可以提供的数据有:客户端源文件名称(FFileName,含路径)、文件大小(FFileDataEnd-FFileDataStart 1)。

首先应该在TLB设计窗口中声明如下两个方法GetFileName和GetFileSize。

1、返回客户端源文件名称(含路径)

//返回客户端源文件名称(含路径)

function TUploadFile.GetFileName: OleVariant;

begin

result := FFileName;//客户端源文件名称(含路径)

end;

2、返回文件大小

//返回文件大小(Bytes)

function TUploadFile.GetFileSize: OleVariant;

begin

result := FFileDataEnd - FFileDataStart 1;

end;


(四)保存文件

在进行了(二)的操作之后,我们的上载组件可以根据ASP程序的要求保存文件了。首先应该在

TLB设计窗口中声明如下两个方法SaveFileAs和SaveFile。

1、按指定文件名称保存文件

//按指定的文件名称保存文件,参数FileName为指定的文件名称,返回值True表示文件保存成功

function TUploadFile.SaveFileAs(FileName: OleVariant): OleVariant;

var

longIndex : LongInt;

AFile : file of byte;//以二进制的形式保存文件

byteData : Byte;

begin

result := true;

try

assign( AFile, FileName );

rewrite( AFile );

for longIndex := FFileDataStart to FFileDataEnd do

begin

byteData := Byte( FContentData[ longIndex ] );

Write( AFile, byteData );

end;

CloseFile( AFile );

except

result := false;

end;

end;

2、按缺省文件名称保存文件

//按缺省文件名称保存文件,将文件以同名文件保存在调用页面所在目录

function TUploadFile.SaveFile: OleVariant;

var

CurrentFilePath : string;

begin

//获取调用页面所在目录

CurrentFilePath := FScriptingContext.Request.ServerVariables['PATH_TRANSLATED'];

CurrentFilePath := ExtractFilePath( CurrentFilePath );

//保存文件

result := SaveFileAs( CurrentFilePath ExtractFileName( FFileName ));

end;


三、上载组件应用举例

在我们的例子中,DelphiUp.HTM是文件上载界面,DelphiUp.ASP用来执行文件上载操作。

DelphiUp.ASP的代码如下:

<!--DelphiUp.ASP:文件上载处理页面-->

<html><head><title>文件上载</title></head><body>

<% dim Upload, FileName

set Upload = Server.CreateObject("MyUpload.UploadFile")

FileName = Upload.GetFileName

Response.Write "<br>正在保存文件《"&FileName&"》......"

if Upload.SaveFile then

Response.Write "<br>文件《"&FileName&"》上载成功。"

Response.Write "<br>文件大小为"&Upload.GetFileSize&"字节。"

else

Response.Write "<br>文件《"&FileName&"》上载失败。"

end if

set Upload=nothing %>

</body></html>


四、几点说明

1、由DELPHI自动生成的源代码编译的DLL文件大小有215K,可以在

ASPTypeLibrary_TLB.PAS的Interface段中将Uses中的单元除ActiveX外全部删除,在

MyUpload_TLB.PAS中删除Uses中所有单元,则生成的DLL文件大小可减少到61K。

2、以上方法同样适用于CGI程序,不过要用TWebRequest对象。


以上程序在PWIN98 Delphi3.0 PWS4.0下调试通过。

粤ICP备06119539号
Copyright CiscoSky.Org,Some Rights Reserved.
Email:me1228#tom.com