第三重:集成类、多语种通用,使用方便
这个问题已经不是什么新鲜问题了,网上也有大把的教程,但大多数是授人以鱼,而不授人以渔,经过辛苦的资料收集,思考,调试,整理,我基本上已经把这个问题从原理上搞清楚了,现在根据我自己的理解,在范例程序的基础上,加以解释,希望能对部分网友(比我还菜的:-))有所帮助。
请诸位大虾能对其中的不正或不良这处予以指正。
程序中stream对象的用法上参考了“化境HTTP上传程序 Version 2.0”在代码,在此对稻香老农和梁无惧表示衷心的感谢和由衷的敬意。
先来分析一下,为后面的数据分析算法打点基础,以下是我摘录的一小段网页中提交的二进制数据: -----------------------------7d31ec15102d0 Content-Disposition: form-data; name="txtTitle"
满脑的想法 -----------------------------7d31ec15102d0 Content-Disposition: form-data; name="filImage"; filename="F:\material\木纹背景\pic016.jpg" Content-Type: image/pjpeg
�? JFIF � C !!E.'.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE?" � � ? } !1AQa"q2亼?#B绷R佯$3br? 侼s歊J佦=ǜ珻,%??Xm 銓鼽?幮??驲湕胄滙C? 儗 g?咶? tS?B矠:u隠c g不t凄L琰h`啨0p g殲41?9'$筵奆]眬?膁?摍? 渦"?�? -----------------------------7d31ec15102d0 Content-Disposition: form-data; name="btnUpload"
Upload -----------------------------7d31ec15102d0--
蓝色的字符的内容我们应该熟悉吧,中间的乱码就是上传的文件的内容,其实我们要做的就是将这一堆数据进行分析,挑出对我们有用的数据保存下来就OK了。分析数据就是查找一些标志性的内容,如回车换行符,“----------”符号,用两个指针确定两个位置,然后提取数据,我的算法不知道好不好,本人的数据结构是学得很烂的,十分sorry。
以下是一个完事的应用,其中的类定义可以与入另一个文件,使用的时候只要用
<!--include file="LjUpload.cls"-->
命令包含进来就可以了。
LjUpload.asp:
<%@ Language=VBScript %> <% option explicit %>
<script language=vbscript runat=server>
private srmRequestData 'adodb.stream对象,保存从form中提交来的所有数据
private adTypeBinary 'adodb.stream对象的叁数:返回二进制数据 private adTypeText 'adodb.stream对象的叁数:返回文本数据 private adModeRead 'adodb.stream对象的叁数:对象可读 private adModeWrite 'adodb.stream对象的叁数:对象可写 private adModeReadWrite 'adodb.stream对象的叁数:对象可读写
class LjUpload '定义一个类,名称为LjUpload。 private bytCrLf '单字节的回车换行符,共2字节 private bytSub '单字节的“-”符号,共8字节 private binData '二进制数据变量,保存一个提交数据的复本,便於操作
private dicForm '保存form文本域的信息 private dicFile '保存form文件域的信息 private strName 'form表单的输入域名称 private strValue 'form表单的输入域值 private objFile '文件信息对象,保存文件相关的信息,具体叁看class LjFile的定义
private posB '二进制数据读写指针,开始指针 private posE '二进制数据读写指针,结束指针 public Charset '语言属性设置 private sub Class_Initialize '类初始化过程 bytCrLf = getSBfromDB(vbcrlf) bytSub = getSBfromDB("--------") Charset = "gb2312" '默认语言属性设置为简体中文:gb2312 adTypeBinary = 1 '返回二进制数据 adTypeText = 2 '返回文本数据 adModeRead = 1 '对象数据可读 adModeWrite = 2 '对象数据可写 adModeReadWrite = 3 '对象数据可读写 end sub public sub GetData '类的打开过程,上传文件及分析数据的过程 set srmRequestData = server.CreateObject("adodb.stream") '建立一个adodb.stream对象 srmRequestData.Type = adTypeBinary '指定返回数据类型 srmRequestData.Mode = adModeReadWrite '指定打开模式 srmRequestData.Open '打开对象 srmRequestData.Write request.BinaryRead(request.TotalBytes) '获取所有form提交的数据 srmRequestData.Position = 0 '读写指针重新定位至对象头部,写数据,指针已指向对象尾 binData = srmRequestData.Read '在变量中保存提交数据的复本,便於操作 set dicForm = server.CreateObject("scripting.dictionary") '用来保存文本信息 set dicFile = server.CreateObject("scripting.dictionary") '用来保存文件信息
posB = instrb(binData,bytSub) '开始分析所获取的二进制数据 posB = instrb(posB,binData,bytCrLf) + 2 '+2是加入回车换行符本身的长度 posB = instrb(posB,binData,getSBfromDB("name=""")) + 6 do until posB = 6 '控制条件的设置有多种方式,这里的仅供叁考 posE = instrb(posB,binData,getSBfromDB("""")) strName = getTextfromBin(srmRequestData,posB,posE-posB) posB = posE + 1 '指针移动到“"”的後面 posE = instrb(posB,binData,bytCrLf) if instrb(midb(binData,posB,posE-posB),getSBfromDB("filename=""")) > 0 then '这是一个file域 posB = instrb(posB,binData,getSBfromDB("filename=""")) + 10 posE = instrb(posB,binData,getSBfromDB("""")) set objFile = new LjFile '建立一个文件信息对象 if posE>posB then objFile.FileName = getFileNamefromPath(getTextfromBin(srmRequestData,posB,posE-posB)) '写入文件名称 posB = instrb(posB,binData,getSBfromDb("Content-Type:")) + 14 posE = instrb(posB,binData,bytCrLf) objFile.ContentType = getTextfromBin(srmRequestData,posB,posE-posB) '写入文件类型 posB = posE + 4 '这个地方换了两行,具体叁看输出的原始二进制数据 posE = instrb(posB,binData,bytSub) objFile.FileBegin = posB objFile.FileLen = posE-posB-2 '写入文件长度信息,-2是减去一个回车符 end if dicFile.Add strName, objFile set objFile = nothing '释放文件信息对象 else '这是一个文本域 posB = posE + 4 '这个地方换了两行,具体叁看输出的原始二进制数据 posE = instrb(posB,binData,bytSub) - 2 strValue = getTextfromBin(srmRequestData,posB,posE-posB) dicForm.Add strName, strValue end if posB = posE + 2 posB = instrb(posB,binData,bytCrLf) + 2 posB = instrb(posB,binData,getSBfromDB("name=""")) + 6 loop '当循环结束时分析二进制数据完成 end sub private function getTextfromBin(srmSource,posBegin,posLen) '二进制数据转换为字符串,包括汉字 dim srmObj, strData set srmObj = server.CreateObject("adodb.stream") srmObj.Type = 1 srmObj.Mode = 3 srmObj.Open srmSource.position = posBegin-1 '位置计数首数不一样,这个对像是对0开始的 srmSource.CopyTo srmObj,posLen srmObj.Position = 0 srmObj.Type = 2 srmObj.Charset = Charset '语言属性设置 strData = srmObj.ReadText srmObj.Close set srmObj = nothing getTextfromBin = strData end function
private function getSBfromDB(bytString) '双字节字符串转换成单字节字符串 dim bin, i bin = "" for i=1 to len(bytString) bin = bin & chrb(asc(mid(bytString,i,1))) next getSBfromDB = bin end function
private function getDBfromSB(bitString) '单字节字符串转换成双字节字符串 dim str, i str = "" for i=1 to lenb(bitString) str = str & chr(ascb(midb(bitString,i,1))) next getDBfromSB = str end function
private function getFileNamefromPath(strPath) '从一个完整路径中析出文件名称 getFileNamefromPath = mid(strPath,instrrev(strPath,"\")+1) end function
public sub about() '关於类过程 dim html html = "<table border=1 cellpadding=2 cellspacing=1>" & "<tr>" & _ "<td style='font-family:verdana;' bgcolor=yellow> <marquee width=160 " & _ "onmouseover='this.stop();' onmouseout='this.start();'>" & _ "<a href=mailto:java300@163com target=_blank>LiJun Upload Class V1.0</a>" & _ "</marquee> </td>" & "</tr>" & "</table>" Response.Write html end sub public function Form(strFormName) '求表单内容的函数 if dicForm.Exists(strFormName) then Form = dicForm(strFormName) else Form = "" end if end function public function File(strFormName) '求文件内容的函数 if dicFile.Exists(strFormName) then set File = dicFile(strFormName) else set File = new LjFile end if end function private sub Class_Terminate '类终止过程 dicForm.RemoveAll set dicForm = nothing dicFile.RemoveAll set dicFile = nothing srmRequestData.Close set srmRequestData = nothing end sub end class
class LjFile '文件类 public FileName '文件名 public ContentType '文件类型 public FileBegin '文件数据开始位置 public FileLen '文件长度,字节数 private sub Class_Initalize FileName = "" ContentType = "" FileBegin = 0 FileLen = 0 end sub public sub SaveToFile(FilePath) '文件保存到磁盘上,FilePath为完整路径,包括文件名 dim srmObj set srmObj = server.CreateObject("adodb.stream") srmObj.Type = adTypeBinary srmObj.Mode = adModeReadWrite srmObj.Open srmRequestData.Position = FileBegin-1 srmRequestData.CopyTo srmObj, FileLen srmObj.Position = 0 srmObj.SaveToFile FilePath, 2 '如果该文件已经存在,无条件覆盖,以後根据需要再行完善 srmObj.Close set srmObj = nothing end sub public function GetBinaryData() srmRequestData.Position = FileBegin-1 GetBinaryData = srmRequestData.Read(FileLen) end function end class </script>
<HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0"> <meta http-equiv="content" content="text/html;charset=gb2312"> <TITLE>ASP无组件上传类:LjUpload</TITLE> </HEAD> <BODY> <% if request.ServerVariables("REQUEST_METHOD") = "POST" then
dim upload set upload = new LjUpload upload.Charset = "gb2312" '设置文本信息的语言属性 upload.GetData() dim title, filImage title = upload.Form("txtTitle") Response.Write title & "<br>" set filImage = new LjFile '这句可不用,此处仅为写代码方便 set filImage = upload.File("filImage") Response.Write filImage.FileName & "<br>" ' 以文件形式保存到磁盘,文件名是当前日期时间的处理值 filImage.SaveToFile server.MapPath("./") & "\" & replace(replace(replace(now(),"/","_")," ","_"),":","_") & "." & right(filImage.FileName,3) ' 保存到数据库用以下的代码 ' dim cn, rs, sql ' set cn = server.CreateObject("adodb.connection") ' cn.Open "driver={Microsoft Access Driver (*.mdb)};dbq=" & server.MapPath("upload.mdb") ' set rs = server.CreateObject("adodb.recordset") ' sql = "select title,[content-type],image from tblImage" ' rs.Open sql,cn,1,3 ' rs.AddNew ' rs.Fields("title").Value = title ' rs.Fields("content-type").Value = filImage.ContentType
' rs.Fields("image").AppendChunk filImage.GetBinaryData()
' rs.Update ' rs.Close ' set rs = nothing ' cn.Close ' set cn = nothing
upload.about() '关於类信息 set filImage = nothing set upload = nothing end if %> <form id="frmUpload" name="frmUpload" action="<%=Request.ServerVariables("script_name")%>" method="post" target="_self" enctype="multipart/form-data"> <p>标题:<input id="txtTitle" type="text" name="txtTitle" size="40"></p> <p>图片:<INPUT id="filImage" type="file" name="filImage" size="40"></p> <INPUT id="btnUpload" type="submit" value="Upload" name="btnUpload"> </form> </BODY> </HTML>
完。

|