分享
 
 
 

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

王朝asp·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

在解码速度方面,化境 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, FFi

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有