分享

摘录网络 asp 上传代码 支持大文件上传

 妹米 2009-09-05
<%@ Language="VBScript" CodePage=65001%>
<%Option Explicit%>
<%

'Code: 200(上传成功)、504(文件为空)、502(上传上限)、501(表示网络中断)、500(上传错误)、
'
505(文件类型禁止上传), 506(未设置允许的文件后缀), 507(未设置上传路径)
'
--------------------------------------------------------------------------------------
'
--------------------------------------------------------------------------------------
Server.ScriptTimeout = 99999999
Response.Buffer 
= True
Response.Charset 
= "utf-8"
Const UPLOAD_PATH = "/upload/"
Class Upload_Cls
    
Private objUpStream, objConvertStream, objFso
    
Private lngMaxSize, lngRequestBytes, lngReadChunkBytes
    
Private strCode
    
Private strFileSuffix, strFilename, strAllowSuffix, strFilePath, lngFileSize, i
    
    
Private Sub Class_Initialize()
        Code 
= 0
        MaxSize 
= 0
        lngReadChunkBytes 
= 131072 '64KB
        lngRequestBytes = CLng(Request.TotalBytes)
    
End Sub

    
Private Sub Class_Terminate()
        
If IsObject(objUpStream) Then
            objUpStream.Close
            
Set objUpStream = Nothing
            
Set objConvertStream = Nothing
        
End if
    
End Sub

    
'------
    '定义允许上传的文件格式, 用英文逗号隔开(,) 形如: gif,jpg
    '------
    Public Property Let AllowSuffix(strVal)
        strAllowSuffix 
= LCase(strVal)
    
End Property
    
    
Public Property Get FileName()
        FileName 
= strFileName
    
End Property

    
Public Property Let FileName(strVal)
        strFileName 
= strVal
    
End Property
    
'------
    '获取上传的文件后缀名
    '------
    Public Property Get FileSuffix()
        FileSuffix 
= strFileSuffix
    
End Property

    
Public Property Let FileSuffix(strVal)
        strFileSuffix 
= strVal
    
End Property

    
'------
    '获取上传文件大小 单位:KB
    '------
    Public Property Get FileSize()
        FileSize 
= lngFileSize
    
End Property
    
    
Private Property Let FileSize(lngVal)
        lngFileSize 
= lngVal
    
End Property
    
    
'-------
    '获取上传文件相对路径
    '-------
    Public Property Get FilePath()
        FilePath 
= strFilePath
    
End Property

    
'-------
    '设置上传文件路径
    '-------
    Public Sub SetFilePath(strCurpath, n)
        
Dim intRnd
        
Select Case n
            
Case Else
                
Randomize
                intRnd 
= Int(9000 * Rnd)
                
Randomize
                intRnd 
= intRnd + Int(100 * Rnd)
                strFilePath 
= strCurpath & FormatTimePattern(Now(), "ymd"& "/"
        
End Select
        
Call CreateFolder(Server.MapPath(FilePath))
    
End Sub

    
'------
    Rem 根据时间生成的文件名
    '------
    Public Function AutoFilePath()
        AutoFilePath 
= FilePath & FileName
    
End Function
    
    
Public Function FormatTimePattern(dateSTime, strPattern)
        
Dim dateTime, strVal
        dateTime 
= dateSTime
        strVal 
= strPattern
        strVal 
= Replace(strVal, "y"Year(dateTime))
        strVal 
= Replace(strVal, "m", Fill0Char(Month(dateTime)))
        strVal 
= Replace(strVal, "d", Fill0Char(Day(dateTime)))
        strVal 
= Replace(strVal, "h", Fill0Char(Hour(dateTime)))
        strVal 
= Replace(strVal, "n", Fill0Char(Minute(dateTime)))
        strVal 
= Replace(strVal, "s", Fill0Char(Second(dateTime)))
        FormatTimePattern 
= strVal
    
End Function

    
Private Function Fill0Char(strVal)
        
If Len(strVal) < 2 Then
            Fill0Char 
= "0" & strVal
        
Else
            Fill0Char 
= strVal
        
End If
    
End Function
    
'------
    '设置上传文件大小上限(单位: Bytes), 默认4096KB
    '------
    Public Property Let MaxSize(lngVal)
        lngMaxSize 
= FormatNum(lngVal, 4194304)
    
End Property
    
    
'------
    '返回上传状态代码
    '------    
    Public Property Get Code()
        Code 
= strCode
    
End Property

    
Private Property Let Code(strVal)
        strCode 
= strVal
    
End Property
    
    
Public Sub GetFileData()
        
Dim binCrLf, binBoundary
        
Dim lngFirstBoundary, lngEndBoundary
        
Dim strInfoHeader, strFieldName, strContentType, strItemValue
        
Dim objFileStream
        
Dim intPos'临时位置
        strContentType = ""
        
If lngRequestBytes < 1 Then
            Code 
= 504
            
Exit Sub
        
End If
        
If lngMaxSize <> 0 And lngRequestBytes > lngMaxSize Then
            Code 
= 502
            
Exit Sub
        
End If
        
Set objUpStream = Server.CreateObject("Adodb.Stream")
        objUpStream.Mode 
= 3
        objUpStream.Type 
= 1
        objUpStream.Open
        
Set objConvertStream = Server.CreateObject("adodb.stream")
        objConvertStream.Mode 
= 3
        objConvertStream.Charset 
= "utf-8"

        binCrLf 
= ChrB(13& ChrB(10'换行符
        lngFirstBoundary = ParseChunk(objUpStream, binCrLf, 1)
        binBoundary 
= SubBinString(1, lngFirstBoundary - 1'取得边界串
        Set objFileStream = New FileInfo_Cls
        
Do While StrComp(SubBinString(lngFirstBoundary, 2), binCrLf) = 0
            lngFirstBoundary 
= lngFirstBoundary + 2
            
Rem Begin 分解表单项目
            If strContentType = "" Then
            
Do While True
                lngEndBoundary 
= ParseChunk(objUpStream, binCrLf, lngFirstBoundary)
                strInfoHeader 
= SubString(lngFirstBoundary, lngEndBoundary - lngFirstBoundary)
                lngFirstBoundary 
= lngEndBoundary + 2
                intPos 
= InStr(strInfoHeader, ":")
                
If intPos = 0 Then Exit Do
                
If intPos > 0 Then
                    
If StrComp(Left(strInfoHeader,intPos - 1),"Content-Disposition"1= 0 Then
                        
'取表单项名称
                        strFieldName = ExtractValue(strInfoHeader,intPos + 1,"name")
                        
'取文件路径,取文件名称
                        FileName = ExtractFileName(ExtractValue(strInfoHeader,intPos + 1,"filename"))

                        
If Not CheckSuffix(FileName) Then Exit Sub
                    
ElseIf StrComp(left(strInfoHeader, intPos - 1),"Content-Type",1= 0 Then
                        
'取文件类型
                        strContentType = Trim(Mid(strInfoHeader, intPos + 1))
                    
End If
                
End If
            
Loop
            
End If
            
Rem End 表单项目结束
            If FileName <> "" Then
                
'掐头后移入流对象
                MoveStream objUpStream, objFileStream.Stream, lngFirstBoundary
                lngEndBoundary 
= ParseChunk(objFileStream.Stream, binBoundary & binCrLf, 1)
                
'流对象去尾
                MoveStream objFileStream.Stream, objUpStream, lngEndBoundary
                lngFirstBoundary 
= lngFirstBoundary + 2 + LenB(binBoundary)
            
Else
                lngEndBoundary 
= ParseChunk(objUpStream, binBoundary, lngFirstBoundary)
                strItemValue 
= SubString(lngFirstBoundary, lngEndBoundary - 2 - lngFirstBoundary)

                
'移动位置
                lngFirstBoundary = lngEndBoundary + LenB(binBoundary)
            
End If
        
Loop
        Code 
= 200
        FileSize 
= objFileStream.FileSize
        
Set objFso = Server.CreateObject("Scripting.FileSystemObject")
        
Call CheckFile
        
Set objFso = Nothing
        objFileStream.SaveAs(Server.MapPath(AutoFilePath))
        
Set objFileStream = Nothing
    
End Sub

    
Private Sub CheckFile()
        
If objFso.FileExists(Server.MapPath(AutoFilePath)) Then
            FileName 
= "[1]" & strFileName
            
Call CheckFile
        
End If
    
End Sub

    
Private Function ExtractValue(strString, startPos, strName)
        
Dim strVal
        
Dim strCurPos, intCurPos
        
Dim n1, n2
        strVal 
= strString
        strCurPos 
= strName & "="""
        intCurPos 
= InStr(startPos, strVal, strCurPos)
        
If intCurPos > 0 Then
            n1 
= intCurPos + Len(strCurPos)
            n2 
= InStr(n1, strVal, """")
            
if n2 > n1 then ExtractValue = Mid(strVal, n1, n2 - n1)
        
End If
    
End Function

    
Private Function SubBinString(StartPos, ReadLen)
        
Dim lngStartPos, lngReadLen
        
Dim binBoundary
        lngReadLen 
= ReadLen
        
If lngReadLen = 0 Then SubBinString = "" : Exit Function
        lngStartPos 
= StartPos
        
If objUpStream.Size < lngStartPos + lngReadLen - 1 Then ReadChunk2Stream objUpStream
        objUpStream.Position 
= lngStartPos - 1
        binBoundary 
= objUpStream.Read(lngReadLen)
        SubBinString 
= MidB(binBoundary, 1)
    
End Function
    
    
Private Function SubString(StartPos, ReadLen)
        
Dim lngStartPos, lngReadLen
        
Dim binBoundary
        lngReadLen 
= ReadLen
        
If lngReadLen = 0 Then SubString = "" : Exit Function
        lngStartPos 
= StartPos
        
If objUpStream.Size < (lngStartPos + lngReadLen - 1Then ReadChunk2Stream objUpStream
        objUpStream.Position 
= lngStartPos - 1
        binBoundary 
= objUpStream.Read(lngReadLen)
        
With objConvertStream
            .Type 
= 1
            .Open
            .Write binBoundary
            .Position 
= 0
            .Type 
= 2
            SubString 
=    .ReadText
            .Close
        
End With
    
End Function
    
    
Rem 解析一个块
    Private Function ParseChunk(obj, Boundary, StartPos)
        
'读取块的起始位置, 找到边界的位置(0表示没有)
        Dim lngStartPos, lngFoundPos, lngBoundaryLen
        
Dim binChunk
        lngStartPos 
= StartPos
        lngFoundPos 
= 0
        lngBoundaryLen 
= LenB(Boundary)
        
Do While lngFoundPos = 0
            
'数据流长度不够时,读取一个块(lngReadChunkBytes)
            If obj.Size < (lngStartPos + lngBoundaryLen - 1Then ReadChunk2Stream obj
            obj.Position 
= lngStartPos - 1
            binChunk 
= obj.Read
            lngFoundPos 
= InstrB(binChunk, Boundary)
            
'未找到边界,则向后移动一个位置
            If lngFoundPos = 0 Then lngStartPos = lngStartPos + LenB(binChunk) - lngBoundaryLen + 1
        
Loop
        ParseChunk 
= lngStartpos + lngFoundPos - 1
    
End Function
    
    
Private Sub ReadChunk2Stream(obj)
        
If Response.IsClientConnected = False then Code = 501 : Exit Sub
        obj.Position 
= obj.Size
        obj.Write Request.BinaryRead(lngReadChunkBytes)
    
End Sub
    
    
Private Sub MoveStream(FromStream, ToStream, StartPos)
        FromStream.Position 
= StartPos - 1
        ToStream.Position 
= ToStream.Size
        FromStream.CopyTo ToStream
        FromStream.Position 
= StartPos - 1
        
'将流对象的结束设定到当前 位置
        FromStream.SetEOS
    
End Sub

    
Private Function ExtractFileName(strString)
        
Dim strVal
        strVal 
= Replace(strString, Chr(0), "")
        strVal 
= Replace(strVal, " """)
        strVal 
= Replace(strVal, "..""")
        strVal 
= Replace(strVal,"'","")
        strVal 
= Replace(strVal,"[","")
        strVal 
= Replace(strVal,"]","")
        strVal 
= Replace(strVal,"<","")
        strVal 
= Replace(strVal,">","")
        strVal 
= Replace(strVal, "*""")
        strVal 
= Replace(strVal, "&""")
        ExtractFileName 
= Mid(strVal, InStrRev(strVal, ""+ 1)
    
End Function
    
    
Private Function CheckSuffix(strA)
        
Dim strSeparate, strTempFileSuffix
        CheckSuffix 
= True
        strSeparate 
= ",asp,asa,cer,aspx,php,cdx,htr,shtm,shtml,stm,idc,"
        FileSuffix 
= LCase(Mid(strA, InStrRev(strA, "."+ 1))

        strTempFileSuffix 
= "," & strFileSuffix & ","
        
If InStr(strSeparate, strTempFileSuffix) > 0 Then
            Code 
= 505
            CheckSuffix 
= False
            
Exit Function
        
End If
    
End Function
    
    
Private Function CreateFolder(strFolderPath)
        
Dim sPath, i, strTempPath, n, objFso, RootPath
        CreateFolder 
= False
        
Set objFso = Server.CreateObject("Scripting.FileSystemobject")
        
If objFso.FolderExists(strFolderPath) Then
            CreateFolder 
= True
            
Exit Function
        
End If
        RootPath 
= Server.MapPath("/"& ""
        sPath 
= Split(strFolderPath, "")
        strTempPath 
= ""
        n 
= UBound(Split(RootPath, ""))
        
For i = n To UBound(sPath)
            strTempPath 
= strTempPath & sPath(i) & ""
            
If Not objFso.FolderExists(RootPath & strTempPath) Then
                objFso.CreateFolder (RootPath 
& strTempPath)
            
End If
        
Next
        
Set objFso = Nothing
        
If Err = 0 Then
            CreateFolder 
= True
        
Else
            CreateFolder 
= False
        
End If
    
End Function

    
Private Function FormatNum(intVal, DefaultVal)
        
If Not IsNumeric(intVal) Then
            FormatNum 
= Clng(DefaultVal)
        
Else
            FormatNum 
= Clng(intVal)
        
End If
    
End Function

End Class

Class FileInfo_Cls
    
Private objFileStream
    
    
Public Function FileSize()
        
Dim lngSize
        lngSize 
= objFileStream.Size
        FileSize 
= CLng(lngSize / 1024)
    
End Function

    
Public Property Get Stream()
        
Set Stream = objFileStream
    
End Property

    
Public Sub SaveAs(strFilePath)
        
On Error Resume Next
        objFileStream.SaveToFile strFilePath, 
2
        
If Err.Number > 0 Then Response.Write "Upload Err: " & Err.Description & "<br>" : Exit Sub
    
End Sub

    
Private Sub Class_Initialize
        
Set objFileStream = CreateObject("Adodb.Stream")
        objFileStream.Mode 
= 3
        objFileStream.Type 
= 1
        objFileStream.Open
    
End sub
 
    
Private Sub Class_Terminate  
        objFileStream.Close
        
Set objFileStream = Nothing 
    
End sub

End Class

Dim action
Dim objUpload, objFile

action 
= Trim(Request.QueryString("action"))
Response.Write 
"<br>"
Select Case action
    
Case "save"
        
Call Save
    
Case "list"
        
Call FileList
    
Case Else
        
Call Header
End Select
Sub Save()
    
Dim stime, etime
    stime 
= Timer
    
Set objUpload = New Upload_Cls
    objUpload.AllowSuffix 
= ""
    objUpload.MaxSize 
= 0
    objUpload.SetFilePath UPLOAD_PATH, 
1
    
Call objUpload.GetFileData
    etime 
= Timer
    Response.Write 
"上传执行代码Code:" & objUpload.Code & "<br>"
    Response.Write 
"文件路径:" & objUpload.AutoFilePath & "<br>"
    Response.Write 
"文件大小:" & objUpload.FileSize & "KB<br>"
    Response.Write 
"执行时间:" & FormatNumber((etime - stime), 2& "second"
    
Set objUpload = Nothing
    
Call Header
End Sub
Sub Header()
%
>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
<table width="600" border="0" cellspacing="0" cellpadding="0">
<br><br><br><br><br>
    
'Code: 200(上传成功)、504(文件为空)、502(上传上限)、501(表示网络中断)、500(上传错误)、
'
505(文件类型禁止上传), 506(未设置允许的文件后缀), 507(未设置上传路径)
<form action="?action=save" method="post" enctype="multipart/form-data" name="form1">
  
<tr align="center">
    
<td width="80" height="46">选择地址:</td>
    
<td width="300">
<input name="uploadfile" type="file" id="uploadfile" size="30"></td>
    
<td width="60"><input type="submit" name="Submit" value="上 传"></td>
  
</tr>
  
<tr align="center">
    
<td height="20" colspan="3"><input type="button" name="Submit" value="关 闭" onClick="window.close();"></td>
    
</tr>
  
</form>
</table>
<%
End Sub

Sub FileList()
Dim strPath
Dim objFso, objUpload
Dim objFolders, objFiles, Folder, File
Dim strThisPath
Set objUpload = New Upload_Cls
strPath 
= Trim(Request.QueryString("path"))
If Len(strPath) = 0 Then 
    strThisPath 
= UPLOAD_PATH & objUpload.FormatTimePattern(Now(), "ymd"& "/"
ElseIf CStr(LCase(strPath)) ="/upload/" Then
    strThisPath 
= UPLOAD_PATH
Else
    strThisPath 
= UPLOAD_PATH & strPath
End If
%
>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title></title>
<br>

<table width="780" align="center" border="0" cellspacing="1" cellpadding="0" bgcolor="#CCCCCC">
<a href="?action=list&path=/upload/">返回上一个路径:</a>
<br><br>
当前路径:
<%Response.Write strThisPath%>
<br><br>
<tr bgcolor="#EFEFEF">
<td align="center" class="row-path topic">文件夹/文件名</a></td>
<td align="center" height="30">大小</td>
<td align="center">文件类型</td>
<td align="center">创建时间</td>
<td align="center">修改时间</td>
</tr>
<%
Set objFso = Server.CreateObject("Scripting.FileSystemObject")
Set objFolders = objFso.GetFolder(Server.MapPath(strThisPath))
For Each Folder In objFolders.subFolders
%
>
<tr bgcolor="#FFFFFF">
<td height="30"><a href="?action=list&path=<%=Folder.Name%>"><%=Folder.Name%></a></td>
<td align="center"><%=FileSize(Folder.Size)%></td>
<td align="center"><%=Folder.Type%></td>
<td align="center"><a title="创建时间"><%=objUpload.FormatTimePattern(Folder.DateCreated, "y-m-d h:n:s")%></a></td><td><a title="修改时间"><%=objUpload.FormatTimePattern(Folder.DateLastModified, "y-m-d h:n:s")%></a></td>
</tr>
<%
Next

For Each File In objFolders.Files
%
>
<tr bgcolor="#FFFFFF">
<td height="30"><a href="<%=strThisPath & "/" & File.Name%>"><%=File.Name%></a></td>
<td align="center"><%=FileSize(File.Size)%></td>
<td align="center"><%=File.Type%></td>
<td align="center"><a title="创建时间"><%=objUpload.FormatTimePattern(File.DateCreated, "y-m-d h:n:s")%></a></td><td><a title="修改时间"><%=objUpload.FormatTimePattern(File.DateLastModified, "y-m-d h:n:s")%></a></td>
</tr>
<%
Next
Set objFolders = Nothing
Set objFso = Nothing
Set objUpload = Nothing
%
>
</table>
</body>
</html>
<%
End Sub

Function FileSize(intSize)
    FileSize 
= CLng(intSize / 1024& "K"
End Function
%
>

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多