ASP檔案上傳神功 第三重(招勢圖加內功心法) (轉)

amyz發表於2007-11-16
ASP檔案上傳神功 第三重(招勢圖加內功心法) (轉)[@more@]

第三重:整合類、多語種通用,使用方便

  這個問題已經不是什麼新鮮問題了,網上也有大把的教程,但大多數是授人以魚,而不授人以漁,經過辛苦的資料收集,思考,,整理,我基本上已經把這個問題從原理上搞清楚了,現在根據我自己的理解,在範例的基礎上,加以解釋,希望能對部分網友(比我還菜的:-))有所幫助。

  請諸位大蝦能對其中的不正或不良這處予以指正。

  程式中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="btn"

Upload
-----------------------------7d31ec15102d0--

  藍色的字元的內容我們應該熟悉吧,中間的亂碼就是上傳的的內容,其實我們要做的就是將這一堆資料進行分析,挑出對我們有用的資料儲存下來就OK了。分析資料就是查詢一些標誌性的內容,如回車換行符,“----------”符號,用兩個指標確定兩個位置,然後提取資料,我的演算法不知道好不好,本人的資料結構是學得很爛的,十分sorry。

以下是一個完事的應用,其中的類定義可以與入另一個檔案,使用的時候只要用

 <!--include file="LjUpload.cls"--&gt

命令包含進來就可以了。

LjUpload.:


 private srmRequestData   'ado.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.Create("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 dicFo= 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
   l   '當迴圈結束時分析二進位制資料完成
  end sub
  
  private function getTextfromBin(srm,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 = "

" & "" & _
       "" & "" & "
       "onmouseover='this.stop();' onmouseout='this.start();'>" & _
       "300@163target=_blank>LiJun Upload Class V1.0" & _
       "
"
   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_Tenate   '類終止過程
   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





ASP無上傳類:LjUpload


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 & "
"
 set filImage = new LjFile   '這句可不用,此處僅為寫程式碼方便
 set filImage = upload.File("filImage")
 Response.Write filImage.FileName & "
"
' 以檔案形式儲存到磁碟,檔名是當前日期時間的處理值
 filImage.SaveToFile server.MapPath("./") & "" & replace(replace(replace(now(),"/","_")," ","_"),":","_") & "." & right(filImage.FileName,3)
 
' 儲存到用以下的程式碼
' dim cn, rs,
' set cn = server.CreateObject("adodb.connection")
' cn.Open "={Microsoft Access Driver (*.mdb)};dbq=" & server.MapPath("upload.mdb")
' set rs = server.CreateObject("adodb.recordset")
' sql = " 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
%>
 

" method="post" target="_self" enctype="multipart/form-data">
 

標題:


 

圖片:


 
 


完。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-982800/,如需轉載,請註明出處,否則將追究法律責任。

相關文章