-
ASP Adodb.Stream 上传文件到服务器硬盘, 详细注解 By shawl.qiu
摘要:
本文演示了使用 adodb.stream 读取二进制流并保存文件到服务器的操作过程.
使用单个文件框, 上传单一文件.
说明:
由于ASP 的变量类型原因, 如果使用 midB 函数截取二进制流数据赋值给一个变量, 那这个变量就不是二进制流了.
因此, 解决方法是使用 两个 adodb.stream 完成二进制流数据的筛选和保存文件.
也可以使用数据库, 但这明显多了不必要的开销.
鄙人很反感使用数据库保存文件数据的做法, 这未免有点大炮打蚊子的味道, 如果要方便管理文件, 那保存文件地址就足可达到方便管理文件的要求.
要点:
当提交表单的时候, 每一个Field都有自己的头部信息, 如:
- linenum
- ------------sXjkjWPhQ7KvsQ0v4QIFwS Content-Disposition: form-data; name="file"; filename="w4h_h2h.swf" Content-Type: application/x-shockwave-flash
每一个Field 的二进制流部分由两对回车换行符起始, 结束由一对回车换行符结束.
结束的判断有时会出错, 当一个文件长度超过每一个流的限定长度的时候, 会在每一个限定长度后加入回车换行符.
因此, 判断文件结束时应当采用Fields分隔标记, 如:
- linenum
- ------------sXjkjWPhQ7KvsQ0v4QIFwS
但是分隔标记必须为二进制流数据, 才可以准确的判断, 取分隔标记的二进制流可如下(详细请看主内容):
- linenum
- dim fieldMarker ' 定义取二进制流 Field 分隔标记 (内容为二进制)
- fieldMarker=leftB(bRead,inStrB(bRead,chrB(13))-1)
关于HTML 表单域 File 项的详细介绍, 请查阅 RFC 1867:
http://coders.meta.net.nz/~perry/rfc/index-1867.html
主要使用到的技术:
asp内建组件 adodb.stream
一个二进制转为字符串的函数, 用以将 Field 头部信息转换为字符串
一个正则表达式函数, 用以取 Field 头部相关信息
目录:
1. 主内容: Adodb.Stream 上传代码及相关注解
2. 预览 (上传 b.gif)
3. 相关测试文件
shawl.qiu
2006-09-24
http://blog.csdn.net/btbtd
1. 主内容: Adodb.Stream 上传代码及相关注解
- linenum
- <%
- dim id:id=request.queryString("id")
- if id<>"" then
- dim filePath:filePath=server.MapPath("/")&"\" ' 定义上传文件存放目录为站点根目录
- dim lf:lf=chrB(13)&chrB(10) ' 定义二进制回车换行符变量
- dim hct:hct=request.ServerVariables("CONTENT_TYPE") ' 定义内容类型变量
- response.write "request.ServerVariables(""CONTENT_TYPE""): <br/>"
- response.write hct&"<br/>"
- dim bTotal ' 取二进制流字节长度
- bTotal=cLng(request.TotalBytes)
- dim bRead ' 读取二进制流内容
- bRead=request.BinaryRead(bTotal)
- dim bStart:bStart=instrB(bRead,lf&lf)+3 ' 取二进制流文件开始位置 (两个回车换行符)
- dim cTy:cTy=binToStr(midB(bRead,1,bStart-1)) ' 取二进制流 Field 头部信息
- dim fieldMarker ' 定义取二进制流 Field 分隔标记 (内容为二进制)
- fieldMarker=leftB(bRead,inStrB(bRead,chrB(13))-1)
- dim cDesc ' 取 Field 描述信息
- cDesc=fRegExpSgl(cTy,true,true,true,"[\s\S]*?Content-Disposition\: (.*?)\;[\s\S]*","$1")
- dim fldName ' 取 Field 名
- fldName=fRegExpSgl(cTy,true,true,true,"[\s\S]*?name\=\""(.*?)""[\s\S]*","$1")
- dim fileName ' 取文件名
- fileName=fRegExpSgl(cTy,true,true,true,"[\s\S]*filename\=""(.*?)""[\s\S]*","$1")
- dim cTp ' 取 二进制流文件部分 MIME 类型描述
- cTp=fRegExpSgl(cTy,true,true,true,"[\s\S]*?Content-Type\:(.*?)","$1")
- dim bEnd ' 取二进制流文件部分结束位置
- bEnd=inStrB(bStart+6,bRead,fieldMarker)-bStart-3
- response.write "<p/>Binary totalSize:<br/>"
- response.write bTotal
- response.write "<p/>Binary content type:<br/>"
- response.binaryWrite midB(bRead,1,bStart-1)
- response.write "<p/>Binary fields mark:<br/>"
- response.binaryWrite fieldMarker
- response.write "<p/>Content-Disposition:<br/>"
- response.write cDesc
- response.write "<p/>field name:<br/>"
- response.write fldName
- response.write "<p/>file name:<br/>"
- response.write fileName
- response.write "<p/>Content Type:<br/>"
- response.write cTp
- response.write "<p/>Binary Start:<br/>"
- response.write bStart
- response.write "<p/>Binary End:<br/>"
- response.write bEnd
- response.write "<p/>Start of Binary Stream:<br/>----------------------<br/>"
- response.BinaryWrite midB(bRead,bStart,bEnd)
- response.write "<br/><br/>----------------------<br/>End of Binary Stream."
- dim stm ' 定义一个 adodb.stream 源对象 stm, 用以拷贝二进制流文件部分至另一 adodb.stream fromStm
- set stm=createObject("adodb.stream")
- stm.type=1 ' 二进制模式
- stm.mode=3 ' 指定打开模式为读写
- stm.open
- stm.write bRead '写入二进制流内容
- dim fromStm '定义 adodb.stream 对象 fromStm, 以保存文件
- set fromStm=createOBject("adodb.stream")
- with fromStm
- .type=1
- .mode=3
- .open
- stm.position = bStart ' 指定 stm 对象的起始位置, 以变量 bStart 的值为起始位置
- stm.copyTo fromStm, bEnd ' 拷贝 stm 二进制流至 fromStm 对象, 长度为 bEnd 变量的长度
- .saveTofile filePath&fileName,2 ' 保存文件, 如果存在相同名称, 则覆盖
- .close
- end with
- set fromStm=nothing
- stm.close
- set stm=nothing
- function fRegExpSgl(str,glb,igc,mtl,pt,rpt)
- dim re
- set re=new RegExp
- re.global=glb
- re.ignoreCase=igc
- re.multiline=mtl
- re.pattern=pt
- fRegExpSgl=re.replace(str,rpt)
- set re=nothing
- end function 'shawl.qiu code'
- private function binToStr(bin)
- '二进制转为 string (bmp|gif|png|jpg)
- dim i, iByt, sByt, bLen:bLen=lenB(bin)
- for i=1 to bLen
- sByt=midB(bin,i,1):iByt=ascB(sByt)
- if iByt<128 then
- binToStr=binToStr&chr(iByt)
- else:i=i+1
- if i<=bLen then binToStr=binToStr&chr(ascW(sByt&sByt))
- end if
- next 'shawl.qiu'
- end function
- end if
- %>
- <form action="?id=test" method="post" enctype="multipart/form-data" name="form1">
- <br/> <input type="file" name="file"><br>
- <input type="submit" value="Submit">
- </form>
- <a href="?">back</a>
2. 预览 (上传 b.gif)
-
request.ServerVariables("CONTENT_TYPE"):
multipart/form-data; boundary=----------gm6oPtBlETBoggRTjvFXGe
Binary totalSize:
6898 Content Type:
------------gm6oPtBlETBoggRTjvFXGe Content-Disposition: form-data; name="file"; filename="b.gif" Content-Type: image/gif Binary fields mark:
------------gm6oPtBlETBoggRTjvFXGe Content-Disposition:
form-data field name:
file file name:
b.gif Content Type:
image/gif Binary Start:
126 Binary End:
6732 Start of Binary Stream:
----------------------
二进制流...(略)
----------------------
End of Binary Stream. back
3. 相关测试文件
-
b.gif
b.jpg
b.png
b.swf
ASP Adodb.Stream 上传文件到服务器硬盘, 详细注解 By shawl.qiu
最新推荐文章于 2022-03-11 01:26:46 发布