引言
采用WEB技术实现B/S(浏览器/服务器)结构的管理系统是办公自动化的发展趋势基于WEB技术的管理系统由于开发周期短与用户平台无关易于实现交互式应用能对信息进行快速高效的收集处理和发布近几年来得到了迅速发展而ASP技术由于其开发效率高交互性好安全性强等特点逐渐成为开发管理系统的首选工具
许多基于WEB的应用都涉及文件上传操作常见的文件上传技术有基于HTTP协议的基于VB(或DELPHI等编程语言)开发的文件上传组件的基于数据库技术的等等这些方法一般都需要编程者能同时掌握WEB技术数据库技术或CGI技术或组件技术对编程者的要求较高而本文将介绍的利用ASP技术直接实现文件上传功能则只需编程者掌握单一的ASP技术即可大大降低了编程难度
几种文件上传技术的比较
基于HTTP协议
该方法需要编程者利用第三方软件如DELPHIVB等在应用程序中先进行HTTP协议编程然后将待上传文件内容按HTTP协议的格式打包最后向WEB服务器发送上传的请求报文从而实现文件的上传因为DELPHI和VB不能编写完整的WEB网络程序只能编写WEB小应用程序因此该方法只用于功能受限的网络应用
基于VB(或DELPHI等)开发的文件上传组件
该方法利用VB(或DELPHI等编程语言)开发ASP服务器组件实现特定的文件上传服务它首先利用ASP表单功能将文件(二进制格式)从用户端上传到服务器端然后使用VB开发的组件对二进制文件进行处理成为可以正常读写的文件该方法要求编程者不仅掌握ASP语言而且还能利用VB等第三方语言进行组件编程增加了开发的难度
基于数据库技术
该方法和上个方法有类似之处不同的地方在于对上传的二进制文件的处理上它使用数据库来保存二进制文件无论是小型数据库还是大型数据库都提供了存储二进制数据的数据类型只要以Append Chunk方式将数据存入相应的字段就可以了该方法虽然简单可行但是因为每次上传的文件大小都是不一样的因此会对数据库的空间造成很大的浪费降低了数据的访问速度并且使得文件只能在数据库环境下进行访问造成了很大的不便
实例分析
但是利用ASP技术直接实现文件上传功能则只需编程者掌握单一的ASP技术即可
大大降低了编程难度下面我们将通过一个实例来介绍如何使用该方法
文件上传表单
首先需要编写一个能提供文件上传功能的表单程序如下所示
<Form action=uploadasp method=post enctype=multipart/formdata>
上传文件<Input type=file name=file><br>
<input type=submit name=upload value=上传>
</form>
其中enctype参数用来设置表单的MIME编码方式在进行文件(或同时包含文本框)上传时必须将其属性设置为multipart/formdatauploadasp是服务器端对接收到的二进制文件流进行处理的ASP程序在本文的后面将陆续介绍其内容
上传文件格式分析
在处理文件之前我们要先了解上传的文件的具体格式通过编写下面一段简单的ASP程序就可以查看其二进制代码
<%
filesize=RequestTotalBytes 获得上传文件的大小
filedata=RequestBinaryRead(filesize) 获得上传文件的二进制数据
ResponseBinaryWrite filedata 在浏览器上显示二进制数据
%>
分析浏览器上显示的上传文件的二进制代码发现代码包括四个部分(若同时上传多个文件或文本框则代码按上传的先后次序排列格式相同)每一部分的内容是用回车换行符号来进行分隔的
)第一部分(起始标志)
dbd
)第二部分(文件说明)
ContentDisposition: formdata; name=file; filename=C:\Documents and Settings\Administrator\My Documents\Invitationdoc ContentType: application/msword
在此我们可以获得上传文件的文件名称及绝对路径也可以获得文件类型这些信息是正确保存文件所不可缺少的
)第三部分(文件内容)
即文件的二进制内容略
)第四部分(结束标志)
dbd
结合第一部分和第四部分的内容来看dbd(每次上传数值都不一样)起到了分割符的作用它标志着一段数据(当有多个上传内容时)的开始和结束从保存文件所需要的信息来讲我们首先需要从第二部分数据的filename中获得文件名称然后需要正确定位文件的起始位置最后利用ASP技术将二进制文件用本来的文件名保存即可若同时上传多个内容(如多个文本框和文件)也是按同样的方法处理每部分的内容都包含在分割符之中只是文本框和文件的表现形式稍有不同这可以通过具体分析其二进制代码来了解
利用ASP技术实现文件存储
上传文件代码的处理
) 获得分割符代码
从上面的分析我们已经知道分割符起到了分割多个数据段(包括文本框和各种类型的文件)的重要作用前面已经分析过分割符出现在第一个回车换行符号前因此通过下面这段程序就可获得分割符代码
<%
newline=chrB() & chrB() newline表示二进制的回车符
filesize=RequestTotalBytes filesize是上传文件的大小
filedata=RequestBinaryRead(filesize) filedata是上传文件的二进制数据
divider=leftB(filedataclng(instrb(filedatanewline))) divider是分割符
%>
注因为这里处理的都是二进制字节码因此所有的函数都是使用它的二进制版本加了b
) 获得文件(或文本框)内容
() 预备函数(将二进制串转化成字符串)
上传文件的内容不需要经过二进制向字符串的转换过程直接保存就可但是若需提取文本框内容或文件的名称就必须进行转换因此需要编写一个通用的并且适用于汉字的转换函数以下是该函数代码
Function BtoS (bstr)
If not Is Null (bstr) Then
for i = to lenb(bstr)
bchr = midb(bstri+)
If ascb(bchr)> Then 汉字是双字节得两个字符一起处理
temp = temp&chr(ascw(midb(bstr i+ )&bchr))
i = i+
Else
temp = temp&chr(ascb(bchr))
End If
next
End If
BtoS = temp
End Function
() 获得文件(或文本框)内容
在实际的WEB应用中上传操作可能涉及多项内容如多个文本框多个文件等等文件和文本框很好区分文件的数据中包含了filename=字串因此我们写了如下的通用函数既可用于提取文件内容又可提取文本框内容(需进行二进制转换)
Function getdata(byval data byval divider final) data表示二进制串divider表示分割符final表示数据的结束位置
filename=chrb()&chrb()&chrb()&chrb()&chrb()&chrb()&chrb()&chrb()&chrb()&chrb() 字符串filename的二进制表示
bncrlf=chrb()&chrb() 二进制的回车符
startpos = instrb(datadivider)+lenb(divider)+lenb(bncrlf) 开始位置
endpos = instrb(startposdata divider)lenb(bncrlf) 结束位置
part = midb(data startpos endposstartpos) 两个分割符之间的内容
firstline = midb(part instrb(part bncrlf)) 内容之前的说明段
If (instrb(firstlinefilename)=) Then 若为文本框获得文本框字符串内容
stemp=midb(partinstrb(partbncrlf&bncrlf)+lenb(bncrlf&bncrlf)lenb(part)instrb(partbncrlf&bncrlf)+lenb(bncrlf&bncrlf))
getdata=BtoS(stemp)
Else 若为文件获得文件二进制内容
Getdata=midb (part instrb (part bncrlf&bncrlf)+lenb (bncrlf&bncrlf) lenb (part)
instrb(partbncrlf&bncrlf)+lenb(bncrlf&bncrlf))
End If
Final=endpos
End function
在程序中直接调用该函数就可获得所需文件(或文本框)内容如下所示
<%
Content=getdata (data divider position)
%>
) 获得文件名称
前面已经分析过了上传文件数据流的filename=字段里包含了文件的名称和绝对路 径一般来说我们只需提取出路径中的文件名即可以下是程序代码
<%
namepos=instrrev(BS(firstline)chr()) firstline即上面获得的说明部分数据chr()
表示/
filename=midb(firstlinenamepos+lenb(firstline)namepos) 获得文件名称
%>
利用ASP直接实现文件上传功能
传统的ASP程序员只能利用FILESYSTEMOBJECT对象对文本文件(txt)进行移动复制删除等操作若需处理二进制对象则不得不采用本文前面介绍的那些方法来实现但是现在ASP中的ADOSTREAM对象可以同时操作文本对象和二进制对象(可以在下载)利用它就可