ASP Adodb.Stream 上传文件到服务器硬盘, 详细注解 By shawl.qiu

ASP Adodb.Stream 上传文件到服务器硬盘, 详细注解 By shawl.qiu


摘要:
本文演示了使用 adodb.stream 读取二进制流并保存文件到服务器的操作过程.
使用单个文件框, 上传单一文件. 

说明:
由于ASP 的变量类型原因, 如果使用 midB 函数截取二进制流数据赋值给一个变量, 那这个变量就不是二进制流了.
因此, 解决方法是使用 两个 adodb.stream 完成二进制流数据的筛选和保存文件. 
也可以使用数据库, 但这明显多了不必要的开销. 

鄙人很反感使用数据库保存文件数据的做法, 这未免有点大炮打蚊子的味道, 如果要方便管理文件, 那保存文件地址就足可达到方便管理文件的要求.

要点:
当提交表单的时候, 每一个Field都有自己的头部信息, 如:
  1. linenum
  2. ------------sXjkjWPhQ7KvsQ0v4QIFwS Content-Disposition: form-data; name="file"; filename="w4h_h2h.swf" Content-Type: application/x-shockwave-flash

每一个Field 的二进制流部分由两对回车换行符起始, 结束由一对回车换行符结束.
结束的判断有时会出错, 当一个文件长度超过每一个流的限定长度的时候, 会在每一个限定长度后加入回车换行符.
因此, 判断文件结束时应当采用Fields分隔标记, 如:
  1. linenum
  2. ------------sXjkjWPhQ7KvsQ0v4QIFwS

但是分隔标记必须为二进制流数据, 才可以准确的判断, 取分隔标记的二进制流可如下(详细请看主内容): 
  1. linenum
  2.         dim fieldMarker ' 定义取二进制流 Field 分隔标记 (内容为二进制)
  3.             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 上传代码及相关注解
  1. linenum
  2. <%
  3.     dim id:id=request.queryString("id")
  4.     if id<>"" then
  5.         dim filePath:filePath=server.MapPath("/")&"\" ' 定义上传文件存放目录为站点根目录
  6.         dim lf:lf=chrB(13)&chrB(10) ' 定义二进制回车换行符变量
  7.         
  8.         dim hct:hct=request.ServerVariables("CONTENT_TYPE") ' 定义内容类型变量
  9.             response.write "request.ServerVariables(""CONTENT_TYPE""): <br/>"
  10.             response.write hct&"<br/>"
  11.             
  12.         dim bTotal ' 取二进制流字节长度
  13.             bTotal=cLng(request.TotalBytes)
  14.             
  15.         dim bRead ' 读取二进制流内容
  16.             bRead=request.BinaryRead(bTotal)
  17.         
  18.         dim bStart:bStart=instrB(bRead,lf&lf)+3 ' 取二进制流文件开始位置 (两个回车换行符)
  19.         
  20.         dim cTy:cTy=binToStr(midB(bRead,1,bStart-1)) ' 取二进制流 Field 头部信息
  21.             
  22.         dim fieldMarker ' 定义取二进制流 Field 分隔标记 (内容为二进制)
  23.             fieldMarker=leftB(bRead,inStrB(bRead,chrB(13))-1)
  24.             
  25.         dim cDesc ' 取 Field 描述信息
  26.             cDesc=fRegExpSgl(cTy,true,true,true,"[\s\S]*?Content-Disposition\: (.*?)\;[\s\S]*","$1")
  27.             
  28.         dim fldName ' 取 Field 名
  29.             fldName=fRegExpSgl(cTy,true,true,true,"[\s\S]*?name\=\""(.*?)""[\s\S]*","$1")
  30.         
  31.         dim fileName ' 取文件名
  32.             fileName=fRegExpSgl(cTy,true,true,true,"[\s\S]*filename\=""(.*?)""[\s\S]*","$1")
  33.             
  34.         dim cTp ' 取 二进制流文件部分 MIME 类型描述
  35.             cTp=fRegExpSgl(cTy,true,true,true,"[\s\S]*?Content-Type\:(.*?)","$1")
  36.             
  37.         dim bEnd ' 取二进制流文件部分结束位置
  38.             bEnd=inStrB(bStart+6,bRead,fieldMarker)-bStart-3
  39.         
  40.             response.write "<p/>Binary totalSize:<br/>"
  41.             response.write bTotal
  42.             response.write "<p/>Binary content type:<br/>"
  43.             response.binaryWrite midB(bRead,1,bStart-1)
  44.             response.write "<p/>Binary fields mark:<br/>"
  45.             response.binaryWrite fieldMarker
  46.             response.write "<p/>Content-Disposition:<br/>"
  47.             response.write cDesc
  48.             response.write "<p/>field name:<br/>"
  49.             response.write fldName
  50.             response.write "<p/>file name:<br/>"
  51.             response.write fileName
  52.             response.write "<p/>Content Type:<br/>"
  53.             response.write cTp
  54.             response.write "<p/>Binary Start:<br/>"
  55.             response.write bStart
  56.             response.write "<p/>Binary End:<br/>"
  57.             response.write bEnd
  58.             response.write "<p/>Start of Binary Stream:<br/>----------------------<br/>"
  59.             response.BinaryWrite midB(bRead,bStart,bEnd)
  60.             response.write "<br/><br/>----------------------<br/>End of Binary Stream."
  61.         
  62.         dim stm ' 定义一个 adodb.stream 源对象 stm, 用以拷贝二进制流文件部分至另一 adodb.stream fromStm
  63.         set stm=createObject("adodb.stream")
  64.             stm.type=1 ' 二进制模式
  65.             stm.mode=3 ' 指定打开模式为读写
  66.             stm.open
  67.             stm.write bRead '写入二进制流内容
  68.         
  69.             dim fromStm '定义 adodb.stream 对象 fromStm, 以保存文件
  70.             set fromStm=createOBject("adodb.stream")
  71.                 with fromStm
  72.                     .type=1
  73.                     .mode=3
  74.                     .open
  75.                     stm.position = bStart ' 指定 stm 对象的起始位置, 以变量 bStart 的值为起始位置
  76.                     stm.copyTo fromStm, bEnd ' 拷贝 stm 二进制流至 fromStm 对象, 长度为 bEnd 变量的长度
  77.                     .saveTofile filePath&fileName,2 ' 保存文件, 如果存在相同名称, 则覆盖
  78.                     .close
  79.                 end with
  80.             set fromStm=nothing
  81.     
  82.             stm.close
  83.         set stm=nothing
  84.         
  85.         function fRegExpSgl(str,glb,igc,mtl,pt,rpt)
  86.             dim re
  87.             set re=new RegExp
  88.                 re.global=glb
  89.                 re.ignoreCase=igc
  90.                 re.multiline=mtl
  91.                 
  92.                 re.pattern=pt
  93.                 fRegExpSgl=re.replace(str,rpt)
  94.             set re=nothing
  95.         end function 'shawl.qiu code'
  96.         
  97.         private function binToStr(bin)
  98.         '二进制转为 string (bmp|gif|png|jpg)
  99.             dim i, iByt, sByt, bLen:bLen=lenB(bin)
  100.             for i=1 to bLen
  101.                 sByt=midB(bin,i,1):iByt=ascB(sByt)
  102.                 if iByt<128 then
  103.                     binToStr=binToStr&chr(iByt)
  104.                 else:i=i+1
  105.                     if i<=bLen then binToStr=binToStr&chr(ascW(sByt&sByt))
  106.                 end if
  107.             next 'shawl.qiu'
  108.         end function
  109.     end if
  110. %>
  111. <form action="?id=test" method="post" enctype="multipart/form-data" name="form1">
  112.  <br/> <input type="file" name="file"><br>
  113.   <input type="submit" value="Submit">
  114. </form>
  115. <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


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值