?? upload.asp
字號:
<%
'-----------------------------------------------------
' 描述: Asp無組件上傳帶進(jìn)度條
' 作者: 寶玉(www.webuc.net)
' 鏈接: www.pspsoft.com, www.cnforums.net, blog.joycode.com, www.cnblogs.com, www.51js.com
' 版本: 1.0 Beta
' 版權(quán): 本作品可免費(fèi)使用,但是請勿移除版權(quán)信息
' 推薦: asp.net上傳組件(http://www.upload4asp.net/)
'-----------------------------------------------------
Dim DoteyUpload_SourceData
Class DoteyUpload
Public Files
Public Form
Public MaxTotalBytes
Public Version
Public ProgressID
Public ErrMsg
Private BytesRead
Private ChunkReadSize
Private Info
Private Progress
Private UploadProgressInfo
Private CrLf
Private Sub Class_Initialize()
Set Files = Server.CreateObject("Scripting.Dictionary") ' 上傳文件集合
Set Form = Server.CreateObject("Scripting.Dictionary") ' 表單集合
UploadProgressInfo = "DoteyUploadProgressInfo" ' Application的Key
MaxTotalBytes = 1 *1024 *1024 *1024 ' 默認(rèn)最大1G
ChunkReadSize = 64 * 1024 ' 分塊大小64K
CrLf = Chr(13) & Chr(10) ' 換行
Set DoteyUpload_SourceData = Server.CreateObject("ADODB.Stream")
DoteyUpload_SourceData.Type = 1 ' 二進(jìn)制流
DoteyUpload_SourceData.Open
Version = "1.0 Beta" ' 版本
ErrMsg = "" ' 錯誤信息
Set Progress = New ProgressInfo
End Sub
' 將文件根據(jù)其文件名統(tǒng)一保存在某路徑下
Public Sub SaveTo(path)
Upload() ' 上傳
if right(path,1) <> "/" then path = path & "/"
' 遍歷所有已上傳文件
For Each fileItem In Files.Items
fileItem.SaveAs path & fileItem.FileName
Next
' 保存結(jié)束后更新進(jìn)度信息
Progress.ReadyState = "complete" '上傳結(jié)束
UpdateProgressInfo progressID
End Sub
' 分析上傳的數(shù)據(jù),并保存到相應(yīng)集合中
Public Sub Upload ()
Dim TotalBytes, Boundary
TotalBytes = Request.TotalBytes ' 總大小
If TotalBytes < 1 Then
Raise("無數(shù)據(jù)傳入")
Exit Sub
End If
If TotalBytes > MaxTotalBytes Then
Raise("您當(dāng)前上傳大小為" & TotalBytes/1000 & " K,最大允許為" & MaxTotalBytes/1024 & "K")
Exit Sub
End If
Boundary = GetBoundary()
If IsNull(Boundary) Then
Raise("如果form中沒有包括multipart/form-data上傳是無效的")
Exit Sub ''如果form中沒有包括multipart/form-data上傳是無效的
End If
Boundary = StringToBinary(Boundary)
Progress.ReadyState = "loading" '開始上傳
Progress.TotalBytes = TotalBytes
UpdateProgressInfo progressID
Dim DataPart, PartSize
BytesRead = 0
'循環(huán)分塊讀取
Do While BytesRead < TotalBytes
'分塊讀取
PartSize = ChunkReadSize
if PartSize + BytesRead > TotalBytes Then PartSize = TotalBytes - BytesRead
DataPart = Request.BinaryRead(PartSize)
BytesRead = BytesRead + PartSize
DoteyUpload_SourceData.Write DataPart
Progress.UploadedBytes = BytesRead
Progress.LastActivity = Now()
' 更新進(jìn)度信息
UpdateProgressInfo progressID
Loop
' 上傳結(jié)束后更新進(jìn)度信息
Progress.ReadyState = "loaded" '上傳結(jié)束
UpdateProgressInfo progressID
Dim Binary
DoteyUpload_SourceData.Position = 0
Binary = DoteyUpload_SourceData.Read
Dim BoundaryStart, BoundaryEnd, PosEndOfHeader, IsBoundaryEnd
Dim Header, bFieldContent
Dim FieldName
Dim File
Dim TwoCharsAfterEndBoundary
BoundaryStart = InStrB(Binary, Boundary)
BoundaryEnd = InStrB(BoundaryStart + LenB(Boundary), Binary, Boundary, 0)
Do While (BoundaryStart > 0 And BoundaryEnd > 0 And Not IsBoundaryEnd)
' 獲取表單頭的結(jié)束位置
PosEndOfHeader = InStrB(BoundaryStart + LenB(Boundary), Binary, StringToBinary(vbCrLf + vbCrLf))
' 分離表單頭信息,類似于:
' Content-Disposition: form-data; name="file1"; filename="G:\homepage.txt"
' Content-Type: text/plain
Header = BinaryToString(MidB(Binary, BoundaryStart + LenB(Boundary) + 2, PosEndOfHeader - BoundaryStart - LenB(Boundary) - 2))
' 分離表單內(nèi)容
bFieldContent = MidB(Binary, (PosEndOfHeader + 4), BoundaryEnd - (PosEndOfHeader + 4) - 2)
FieldName = GetFieldName(Header)
' 如果是附件
If InStr (Header,"filename=""") > 0 Then
Set File = New FileInfo
' 獲取文件相關(guān)信息
Dim clientPath
clientPath = GetFileName(Header)
File.FileName = GetFileNameByPath(clientPath)
File.FileExt = GetFileExt(clientPath)
File.FilePath = clientPath
File.FileType = GetFileType(Header)
File.FileStart = PosEndOfHeader + 3
File.FileSize = BoundaryEnd - (PosEndOfHeader + 4) - 2
File.FormName = FieldName
' 如果該文件不為空并不存在該表單項(xiàng)保存之
If Not Files.Exists(FieldName) And File.FileSize > 0 Then
Files.Add FieldName, File
End If
'表單數(shù)據(jù)
Else
' 允許同名表單
If Form.Exists(FieldName) Then
Form(FieldName) = Form(FieldName) & "," & BinaryToString(bFieldContent)
Else
Form.Add FieldName, BinaryToString(bFieldContent)
End If
End If
' 是否結(jié)束位置
TwoCharsAfterEndBoundary = BinaryToString(MidB(Binary, BoundaryEnd + LenB(Boundary), 2))
IsBoundaryEnd = TwoCharsAfterEndBoundary = "--"
If Not IsBoundaryEnd Then ' 如果不是結(jié)尾, 繼續(xù)讀取下一塊
BoundaryStart = BoundaryEnd
BoundaryEnd = InStrB(BoundaryStart + LenB(Boundary), Binary, Boundary)
End If
Loop
' 解析文件結(jié)束后更新進(jìn)度信息
Progress.UploadedBytes = TotalBytes
Progress.ReadyState = "interactive" '解析文件結(jié)束
UpdateProgressInfo progressID
End Sub
'異常信息
Private Sub Raise(Message)
ErrMsg = ErrMsg & "[" & Now & "]" & Message & "<BR>"
Progress.ErrorMessage = Message
UpdateProgressInfo ProgressID
'call Err.Raise(vbObjectError, "DoteyUpload", Message)
End Sub
' 取邊界值
Private Function GetBoundary()
Dim ContentType, ctArray, bArray
ContentType = Request.ServerVariables("HTTP_CONTENT_TYPE")
ctArray = Split(ContentType, ";")
If Trim(ctArray(0)) = "multipart/form-data" Then
bArray = Split(Trim(ctArray(1)), "=")
GetBoundary = "--" & Trim(bArray(1))
Else '如果form中沒有包括multipart/form-data上傳是無效的
GetBoundary = null
Raise("如果form中沒有包括multipart/form-data上傳是無效的")
End If
End Function
' 將二進(jìn)制流轉(zhuǎn)化成文本
Private Function BinaryToString(xBinary)
Dim Binary
if vartype(xBinary) = 8 then Binary = MultiByteToBinary(xBinary) else Binary = xBinary
Dim RS, LBinary
Const adLongVarChar = 201
Set RS = CreateObject("ADODB.Recordset")
LBinary = LenB(Binary)
if LBinary>0 then
RS.Fields.Append "mBinary", adLongVarChar, LBinary
RS.Open
RS.AddNew
RS("mBinary").AppendChunk Binary
RS.Update
BinaryToString = RS("mBinary")
Else
BinaryToString = ""
End If
End Function
Function MultiByteToBinary(MultiByte)
Dim RS, LMultiByte, Binary
Const adLongVarBinary = 205
Set RS = CreateObject("ADODB.Recordset")
LMultiByte = LenB(MultiByte)
if LMultiByte>0 then
RS.Fields.Append "mBinary", adLongVarBinary, LMultiByte
RS.Open
RS.AddNew
RS("mBinary").AppendChunk MultiByte & ChrB(0)
RS.Update
Binary = RS("mBinary").GetChunk(LMultiByte)
End If
MultiByteToBinary = Binary
End Function
' 字符串到二進(jìn)制
Function StringToBinary(String)
Dim I, B
For I=1 to len(String)
B = B & ChrB(Asc(Mid(String,I,1)))
Next
StringToBinary = B
End Function
'返回表單名
Private Function GetFieldName(infoStr)
Dim sPos, EndPos
sPos = InStr(infoStr, "name=")
EndPos = InStr(sPos + 6, infoStr, Chr(34) & ";")
If EndPos = 0 Then
EndPos = inStr(sPos + 6, infoStr, Chr(34))
End If
GetFieldName = Mid(infoStr, sPos + 6, endPos - _
(sPos + 6))
End Function
'返回文件名
Private Function GetFileName(infoStr)
Dim sPos, EndPos
sPos = InStr(infoStr, "filename=")
EndPos = InStr(infoStr, Chr(34) & CrLf)
GetFileName = Mid(infoStr, sPos + 10, EndPos - _
(sPos + 10))
End Function
'返回文件的 MIME type
Private Function GetFileType(infoStr)
sPos = InStr(infoStr, "Content-Type: ")
GetFileType = Mid(infoStr, sPos + 14)
End Function
'根據(jù)路徑獲取文件名
Private Function GetFileNameByPath(FullPath)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -