数据读取中...
 您当前位置:惠州维修 -> 网络-> asp技术交流 文章搜索:  
ASP无组件上传·从原理剖析到实践三
作者:转载 来源:惠州维修
日期: 2004-10-6
放大字体显示 缩小字体显示 打印文章 推荐给朋友
第五天:得到文件单元  

今天我们要进行的部分,是比较有趣味性地——得到文件内容。其实,看看我们的要处理的数据,再看看前天文本单元的处理,相信大家也会心中有数。 

为了清晰的区分文件和文本单元,这一次,我们用ourRequest.file(index)来对应文本单元的ourRequest.form(index)。当然,因为对于文件,我们需要得到的信息不同于文本,所以这次得到的,也不会是FormElement,而是一个新对象FileElement。 

文件单元和文本单元在原始数据上,不同点少得可怜: 
1。第一行多了一个filename="xxx"模块; 
2。多了一个用于指示contentType的第二行。 

感兴趣的目标信息不同,所以,得到的对象FileElement也和FormElement有一些不同点: 
1。不需要count属性(不存在checkbox情况); 
2。不需要Item(index)(同上,不存在checkbox情况); 
3。需要一个ContentType属性; 
4。需要一个FilePath属性; 
5。需要一个FileName属性; 
6。需要一个Size属性; 
7。因为需要的是二进制,所以,没有必要进行二进制=>字符串的转换; 
8。因为需要的是二进制,所以,属性value改成Data更合适 

此外,UploadRequest也应该相应的添加Files属性、Form(index)方法、以及m_dicFiles成员。现在,我们就来扩充他: 
A。UploadRequest(上面设计过,这里是扩充) 
这个类和request对象是对应的 
属性: 
 RawData     得到原始数据,方便检查[只读] 
 Forms       得到一个有count属性的计数器, 
             可以用outRequest.Forms.Count的方式,得到文本表单域的的个数[只读] 
 Files       得到一个有count属性的计数器, 
             可以用outRequest.Files.Count的方式,得到文件表单域的的个数[只读] 
 Form(index) 可以用数字或文本检索文本表单域,做用类似request.form。 
             他返回一个FormElement型的对象 
 File(index) 可以用数字或文本检索文件表单域,他返回一个FileElement型的对象 
B。FileElement 
可以把它看成单个文件域的化身。通过这个类,可以得到详细的文件信息,比如name,data,path,filename,contentType,size等等。 
属性: 
 Name        文件域的名称。就是<input type=file name=xxx>里的xxx 
 Data        文件域的内容。二进制串 
 ContentType 文件域的contentType 
 FilePath    文件域包含的文件在客户机上的全路径 
 FileName    文件域包含的文件的文件名 
 Size        文件域包含的文件的尺寸 

这里是实现。还是存成doupload.asp: 
<% 
’========================================================================= 
’’ 这个,是存储文本域信息的的类。每一个name的文本域,对应一个这样的类。 
’========================================================================= 
Class FormElement 

 ’ m_开头,表示类成员变量。 
 Private m_dicItems 

 Private Sub Class_Initialize() 
   Set m_dicItems = Server.CreateObject("Scripting.Dictionary") 
 End Sub 

 ’ count是咱们这个类的一个只读属性 
 Public Property Get Count() 
   Count = m_dicItems.Count 
 End Property 

 ’ value是一个默认属性。目的是得到值 
 Public Default Property Get value() 
   value = Item("") 
 End Property 

 ’ Name是得到文本域名称。就是<input name=xxx>里的xxx 
 Public Property Get Name() 
   Keys = m_dicItems.Keys 
   Name = Keys(0) 
   Name = left(Name,instrrev(Name,"_")-1) 
 End Property 

 ’ Item属性用来得到重名表单域(比如checkbox)的某一个值 
 Public Property Get Item(index) 
   If isNumeric(index) Then ’是数字,合法! 
     If index > m_dicItems.Count-1 Then 
       err.raise 1,"IndexOutOfBound", "表单元素子集索引越界" 
     End If 
     Itms = m_dicItems.Items 
     Item = Itms(index) 
   ElseIf index = "" Then ’没给值?那就返回所有的!逗号分隔 
     Itms = m_dicItems.Items 
     For i = 0 to m_dicItems.Count-1 
       If i = 0 Then 
         Item = Itms(0) 
       Else 
         Item = Item & "," & Itms(i) 
       End If 
     Next 
   Else ’给个一个不是数字的东东?出错! 
     err.raise 2,"IllegalArgument", "非法的表单元素子集索引" 
   End If 
 End Property 

 Public Sub Add(key, item) 
   m_dicItems.Add key, item 
 End Sub 

End Class 

’========================================================================= 
’’ 这个,是存储文件域信息的的类。每一个name的文件,对应一个这样的类。 
’========================================================================= 
Class FileElement 

 ’ m_开头,表示类成员变量。 
 Private m_strName 
 Private m_bData 
 Private m_strContentType 
 Private m_strFilePath 
 Private m_strFileName 
 Private m_lSize 

 ’ Data是一个默认属性。目的是得到值 
 Public Default Property Get Data() 
   Data = m_bData 
 End Property 

 ’ Name是得到文件域名称,就是<input type=file name=xxx>里的xxx 
 Public Property Get Name() 
   Name = m_strName 
 End Property 

 ’ ContentType是得到文件contentType 
 Public Property Get ContentType() 
   ContentType = m_strContentType 
 End Property 

  ’ FilePath是得到文件在客户端的路径 
 Public Property Get FilePath() 
   FilePath = m_strFilePath 
 End Property 

  ’ FilePath是得到文件在客户端的路径 
 Public Property Get FileName() 
   FileName = m_strFileName 
 End Property 

  ’ Size是得到文件大小 
 Public Property Get Size() 
   Size = m_lSize 
 End Property 

 Public Sub Add(name, data, contenttype, path) 
   m_strName = name 
   m_bData = data 
   m_strContentType = contenttype 
   m_strFilePath = path 
   m_strFileName = right(path, len(path)-instrrev(path, "\")) 
   m_lSize = lenb(data) 
 End Sub 

End Class 

’========================================================================= 
’’ 这个,是我们模拟的request类。我们用它完成asp的request完成不了的任务 :) 
’========================================================================= 
Class UploadRequest 

 Private m_dicForms 
 Private m_dicFiles 
 Private m_bFormdata 

 Private Sub Class_Initialize() 
   Set m_dicForms = Server.CreateObject("Scripting.Dictionary") 
   Set m_dicFiles = Server.CreateObject("Scripting.Dictionary") 
   Call fill() 
 End Sub 

 ’ 有了这个,就可以检查原始数据了 
 Public Property Get RawData() 
   RawData = m_bFormdata 
 End Property 

 ’ 这一段丑陋的代码是为了实现outRequest.Forms.Count这个功能。 
 Public Property Get Forms() 
   Set Forms = New Counter 
   Forms.setCount(m_dicForms.Count) 
 End Property 

 ’ 这一段丑陋的代码是为了实现outRequest.Files.Count这个功能。 
 Public Property Get Files() 
   Set Files = New Counter 
   Files.setCount(m_dicFiles.Count) 
 End Property 

 Public Property Get Form(index) 
   If isNumeric(index) Then ’是数字?用数字来检索 
     If index > m_dicForms.Count-1 Then 
       err.raise 1,"IndexOutOfBound", "表单元素索引越界" 
     End If 
     Items = m_dicForms.Items 
     Set Form = Items(index) 
   ElseIf VarType(index) = 8 Then ’字符串?也行! 
     If m_dicForms.Exists(index) Then ’存在,就返回值 
       Set Form = m_dicForms.Item(index) 
     Else ’不存在,就给个空值——request对象就是这么做的。 
       Exit Property 
     End If 
   Else ’给了一个不是数字也不是字符串的东东?出错! 
     err.raise 2,"IllegalArgument", "非法的表单元素索引" 
   End If 
 End Property 

 Public Property Get File(index) 
   If isNumeric(index) Then ’是数字?用数字来检索 
     If index > m_dicFiles.Count-1 Then 
       err.raise 1,"IndexOutOfBound", "文件元素索引越界" 
     End If 
     Items = m_dicFiles.Items 
     Set File = Items(index) 
   ElseIf VarType(index) = 8 Then ’字符串?也行! 
     If m_dicFiles.Exists(index) Then ’存在,就返回值 
       Set File = m_dicFiles.Item(index) 
     Else ’不存在,出错! 
       err.raise 2,"NullRef", "文件元素索引不存在" 
     End If 
   Else ’给了一个不是数字也不是字符串的东东?出错! 
     err.raise 2,"IllegalArgument", "非法的表单元素索引" 
   End If 
 End Property 

 Private Sub fill 
   ’ 得到数据 
   m_bFormdata=request.binaryread(request.totalbytes) 
   ’ 调用这个函数实现递归循环,读取文本/文件单元 
   Call fillEveryFirstPart(m_bFormdata) 
 End Sub 

 Private Sub fillEveryFirstPart(data) 
   ’ 这就是name=" 
   const_nameis=chrb(110)&chrb(97)&chrb(109)&chrb(101)&chrb(61)&chrb(34) 
   ’ 这就是filename=" 
   const_filenameis=chrb(102)&chrb(105)&chrb(108)&chrb(101)&_ 
                chrb(110)&chrb(97)&chrb(109)&chrb(101)&chrb(61)&chrb(34) 
   ’ 这是回车<return> 
   bncrlf=chrb(13) & chrb(10) 
   ’ 得到divider,分隔符 
   divider=leftb(data,instrb(data,bncrlf)-1) 
   ’ 起始位置 
   startpos = instrb(data,divider)+lenb(divider)+lenb(bncrlf) 
   ’ 终止位置,从起始位置开始到下一个divider 
   endpos = instrb(startpos, data, divider)-lenb(bncrlf) 
   If endpos < 1 Then ’没有下一个了!结束! 
     Exit Sub 
   End If 
   part1 = midb(data, startpos, endpos-startpos) 
   ’ 得到part1的第一行 
   firstline = midb(part1, 1, instrb(part1, bncrlf)-1) 

   ’没有filename=",有name=",说明是一个文本单元(这里有一个BUG,自己研究一下?当作业吧) 
   If Not instrb(firstline, const_filenameis) > 0_ 
      And instrb(firstline, const_nameis) > 0 Then 
     ’ 得到表单域名称,就是<input type=sometype name=somename>里的somename。 
     fldname = B2S(midb(part1,_ 
               instrb(part1, const_nameis)+lenb(const_nameis),_ 
               instrb(part1, bncrlf)_ 
                 -instrb(part1, const_nameis)-lenb(const_nameis)-1)) 
     ’ 得到表单域的值 
     fldvalue = B2S(midb(part1,_ 
                instrb(part1, bncrlf&bncrlf)+lenb(bncrlf&bncrlf),_ 
                lenb(part1)-instrb(part1, bncrlf&bncrlf)+lenb(bncrlf&bncrlf))) 
     If m_dicForms.Exists(fldname) Then 
       Set fElement = m_dicForms.Item(fldname) 
       m_dicForms.Remove fldname 
     Else 
       Set fElement = new FormElement 
     End If 

     fElement.Add fldname&"_"&fElement.Count, fldvalue 
     m_dicForms.Add fldname, fElement 

   ’有filename=",有name=",说明是一个文件单元(这里还是有一个BUG,研究出来没?) 
   ElseIf instrb(firstline, const_filenameis) > 0_ 
          And instrb(firstline, const_nameis) > 0 Then 
     ’ 得到表单域名称,就是<input type=file name=somename>里的somename。 
     fldname = B2S(midb(part1,_ 
               instrb(part1, const_nameis)+lenb(const_nameis),_ 
               instrb(part1, const_filenameis)_ 
                 -instrb(part1, const_nameis)-lenb(const_nameis)-3)) 
     ’ 得到表单域的值 
     fldvalue = midb(part1,_ 
                instrb(part1, bncrlf&bncrlf)+lenb(bncrlf&bncrlf),_ 
                lenb(part1)-instrb(part1, bncrlf&bncrlf)+lenb(bncrlf&bncrlf)) 
     ’ 得到路径 
     filepath = B2S(midb(part1,_ 
               instrb(part1, const_filenameis)+lenb(const_filenameis),_ 
               instrb(part1, bncrlf)_ 
                 -instrb(part1, const_filenameis)-lenb(const_filenameis)-1)) 
     ’ 得到contenttype 
     contenttype = B2S(midb(part1,_ 
                   instrb(part1, bncrlf)+lenb(bncrlf)+14,_ 
                   instrb(part1,_ 
                          bncrlf&bncrlf)-instrb(part1, bncrlf)-lenb(bncrlf)-14)) 
     If lenb(fldvalue) > 0 Then ’size>0说明有文件传来了。 
       If m_dicFiles.Exists(fldname) Then 
         Set fElement = m_dicFiles.Item(fldname) 
         m_dicFiles.Remove fldname 
       Else 
         Set fElement = new FileElement 
       End If 

       fElement.Add fldname, fldvalue, contenttype, filepath 
       m_dicFiles.Add fldname, fElement 
     End If 
   End If 
文章页数:[1] 
帮助你我他: 1.我有问题请教 2.我要投稿>>>
更多相关资料搜索:
热点文章
最新文章
相关文章
版权申明:除部分特别声明不要转载,或者授权本站独家播发的文章外,大家可以自由转载本站的原创文章,但原作者和来自本站的链接必须保留(非本站原创的,按照原来自一节,自行链接)。文章版权归本站和作者共有。
转载要求:转载之图片、文件,链接请不要盗链到本站,且不准打上各自站点的水印,亦不能抹去本站水印。
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
发表评论  打印  刷新  推荐给朋友  返回顶部  关闭

网上大名: