·您的位置: 首页 » 资源教程 » 编程开发 » ASP » 时间、空间性能极优的ASP无组件上传类

时间、空间性能极优的ASP无组件上传类

类别: ASP教程  评论数:0 总得分:0
在解码速度方面,化境 2.0 已经非常高了,但是,它还存在以下两个问题:
1、用Data_5xsoft.Write Request.BinaryRead(Request.TotalBytes)一次读取全部数据,以及用RequestData =Data_5xsoft.Read 一次取出全部数据,在上传数据过大时,会由于内存不足,导致上传失败,这里应该采用分段读取方式。
2、保存数据时,需要先从Data_5xsoft中复制到一个临时流中,在保存大文件时,需要两倍的存储资源,在单机状态下测试,可以发现保存时间随文件尺寸急剧增长,甚至超过上传和解码时间。

本人所写的这个类,采用在解码的过程中,逐块读取(注意:块的大小与速度不成正比,单机测试表明,64K的块比1M的块快得多)的方法,解决问题1,同时采用对普通数据,写入工作流;对文件内容,直接写入文件自身的流的方式,解决问题2。

代码如下,用法类似于化境:

Server.ScriptTimeOut = 600

Class QuickUpload
Private FForm, FFile, Upload_Stream, ConvertStream

property get Form
set Form = FForm
end property

property get File
set File = FFile
end property

Private Sub Class_Initialize
dim iStart, iEnd, boundary, FieldName, FileName, ContentType, ItemValue, theFile, LineEnd

set FForm=CreateObject("Scripting.Dictionary")
set FFile=CreateObject("Scripting.Dictionary")
set Upload_Stream=CreateObject("Adodb.Stream")
Upload_Stream.mode=3
Upload_Stream.type=1
Upload_Stream.open
set ConvertStream = Server.CreateObject("adodb.stream")
ConvertStream.Mode =3
ConvertStream.Charset="GB2312"

if Request.TotalBytes<1 then Exit Sub

\'dStart = CDbl(Time)

\'查找第一个边界
iStart = Search(Upload_Stream, ChrB(13)&ChrB(10), 1)
\'取边界串
boundary = subString(1, iStart-1, false)
\'不是结束边界,则循环
do while StrComp(subString(iStart, 2, false),ChrB(13)&ChrB(10))=0
iStart = iStart+2
\'取表单项信息头
do while true
iEnd = Search(Upload_Stream, ChrB(13)&ChrB(10), iStart)
\'分解信息头
line = subString(iStart, iEnd-iStart, true)
\'移动位置
iStart = iEnd+2
if Line="" then Exit do
pos = instr(line,":")
if pos>0 then
if StrComp(left(Line,pos-1),"Content-Disposition",1)=0 then
\'取表单项名称
FieldName = ExtractValue(Line,pos+1,"name")
\'取文件名称
FileName = ExtractValue(Line,pos+1,"filename")
\'删除文件路径
FileName = Mid(FileName,InStrRev(FileName, "")+1)
elseif StrComp(left(Line,pos-1),"Content-Type",1)=0 then
\'取文件类型
ContentType = trim(mid(Line,pos+1))
end if
end if
loop
\'取表单项内容
if FileName<>"" then
\'新建文件内容
set theFile = new FileInfo
theFile.Init FileName, ContentType
\'文件流内容移到文件流中
MoveData Upload_Stream, theFile.Stream, iStart
\'上传数据直接传入文件流,可以减少文件存储时间
iEnd = Search(theFile.Stream, boundary, 1)
\'后继数据移入工作流
MoveData theFile.Stream, Upload_Stream, iEnd-2
\'
FFile.add FieldName, theFile
\'移动位置
iStart = iStart+2+LenB(boundary)
else
\'查找边界
iEnd = Search(Upload_Stream, boundary, iStart)
\'取表单项内容
ItemValue = subString(iStart, iEnd-2-iStart, true)
\'
if FForm.Exists(FieldName) then
FForm.Item(FieldName) = FForm.Item(FieldName) & "," & ItemValue
else
FForm.Add FieldName, ItemValue
end if
\'移动位置
iStart = iEnd+LenB(boundary)
end if
loop
\'Response.Write "parse time:" & FormatNumber((CDbl(Time)-dStart)*24*60*60,-1,-1) & "<br>"
End Sub

Private Function Search(src, str, theStart)
iStart = theStart
pos=0
do while pos=0
\'长度不够,读一块
if src.Size<(iStart+lenb(str)-1) then ReadChunk src
\'取一段数据,约64K,可以减少内存需求
src.Position = iStart-1
buf = src.Read
\'检测边界
pos=InStrB(buf,str)
\'如果未找到,向后移动
if pos=0 then iStart = iStart+LenB(buf)-LenB(str)+1
loop
Search = iStart+pos-1
End function

private sub MoveData(Src, Dest, theStart)
Src.Position = theStart-1
Dest.Position = Dest.Size
Src.CopyTo dest
Src.Position = theStart-1
Src.SetEOS
end sub

private function ExtractValue(line,pos,name)
dim t, p
ExtractValue = ""
t = name + "="""
p = instr(pos,line,t)
if p>0 then
n1 = p+len(t)
n2 = instr(n1,line,"""")
if n2>n1 then ExtractValue = mid(line,n1,n2-n1)
end if
end function

Private Function subString(theStart,theLen, ConvertToUnicode)
if theLen>0 then
\'当长度不够时,读一块数据
if Upload_Stream.Size<theStart+theLen-1 then ReadChunk Upload_Stream
Upload_Stream.Position=theStart-1
Binary =Upload_Stream.Read(theLen)
if ConvertToUnicode then
ConvertStream.Type = 1
ConvertStream.Open
ConvertStream.Write Binary
ConvertStream.Position = 0
ConvertStream.Type = 2
subString = ConvertStream.ReadText
ConvertStream.Close
else
subString = midB(Binary,1)
end if
else
subString = ""
end if
End function

Private Sub ReadChunk(src)
\'读一块,通过一次读64K,可以防止数据量过大时内存溢出
if Response.IsClientConnected = false then Raise "网络连接中断"
BytesRead = 65536
src.Position = src.Size
src.Write Request.BinaryRead(BytesRead)
End Sub

\'异常信息
Private Sub Raise(Message)
Err.Raise vbObjectError, "QuickUpload", Message
End Sub

Private Sub Class_Terminate
form.RemoveAll
file.RemoveAll
set form=nothing
set file=nothing
Upload_Stream.close
set Upload_Stream=nothing
ConvertStream.Close
set ConvertStream=nothing

End Sub

End Class

Class FileInfo
Private FFileName, FFileType, FFileStart, FFileSize, FStream

property get FileName
FileName = FFileName
end property

property get FileType
FileType = FFileType
end property

property get FileSize
FileSize = FStream.Size
end property

property get Stream
set Stream = FStream
end property

Public Sub Init(AFileName, AFileType)
FFileName = AFileName
FFileType = AFileType
End Sub

Public function SaveAs(FullPath)
dim dr,ErrorChar,i
\'dStart = CDbl(Time)
SaveAs=1
if trim(fullpath)="" or right(fullpath,1)="/" then exit function
On Error Resume Next
FStream.SaveToFile FullPath,2
if Err.Number>0 then Response.Write "保存数据出错:" & Err.Description & "<br>"
SaveAs=0
\'Response.Write "save time:" & FormatNumber((CDbl(Time)-dStart)*24*60*60,-1,-1) & "<br>"
end function

Private Sub Class_Initialize
set FStream=CreateObject("Adodb.Stream")
FStream.mode=3
FStream.type=1
FStream.open
end sub

Private Sub Class_Terminate
FStream.Close
set FStream=nothing
end sub
End Class
-= 资 源 教 程 =-
文 章 搜 索
关键词:
类型:
范围:
纯粹空间 softpure.com
Copyright © 2006-2008 暖阳制作 版权所有
QQ: 15242663 (拒绝闲聊)  Email: faisun@sina.com
 纯粹空间 - 韩国酷站|酷站欣赏|教程大全|资源下载|免费博客|美女壁纸|设计素材|技术论坛   Valid XHTML 1.0 Transitional
百度搜索 谷歌搜索 Alexa搜索 | 粤ICP备19116064号-1