디코딩 속도 측면에서 Huajing 2.0은 이미 매우 높지만 여전히 다음과 같은 두 가지 문제가 있습니다.
1. 모든 데이터를 한 번에 읽으려면 Data_5xsoft.Write Request.BinaryRead(Request.TotalBytes)를 사용하고, 업로드된 데이터가 너무 많으면 업로드가 실패할 수 있으므로 RequestData =Data_5xsoft.Read를 사용하십시오. 메모리가 부족합니다. 분할 읽기 방법을 사용해야 합니다.
2. 데이터를 저장할 때 먼저 Data_5xsoft에서 임시 스트림으로 복사해야 합니다. 대용량 파일을 저장할 때 독립 실행형 상태에서 테스트하면 저장 시간이 두 배로 늘어나는 것을 확인할 수 있습니다. 업로드 시간과 디코딩 시간을 초과하더라도 파일 크기가 급격히 증가합니다.
내가 작성한 클래스는 문제 1을 해결하기 위해 디코딩 프로세스 중에 블록 단위로 읽는 방법을 사용합니다(참고: 블록의 크기는 속도에 비례하지 않습니다. 단일 머신 테스트에서는 64K 블록이 1M 블록보다 훨씬 빠르다는 것을 보여줍니다). . 동시에 일반 데이터를 워크플로에 쓰고 파일 내용을 파일 자체 스트림에 직접 쓰는 방법을 사용하여 문제 2를 해결합니다.
코드는 다음과 같으며 사용법은 Huajing과 유사합니다.
Server.ScriptTimeOut = 600
Class QuickUpload
비공개 FForm, FFile, Upload_Stream, ConvertStream
부동산 양식 받기
setForm = FForm
끝 속성
속성 파일 가져오기
setFile = F파일
끝 속성
비공개 하위 클래스_초기화
희미한 iStart, iEnd, 경계, FieldName, FileName, ContentType, ItemValue, theFile, LineEnd
set FForm=CreateObject("Scripting.Dictionary")
set FFile=CreateObject("Scripting.Dictionary")
Upload_Stream=CreateObject("Adodb.Stream") 설정
Upload_Stream.mode=3
Upload_Stream.type=1
Upload_Stream.open
ConvertStream = Server.CreateObject("adodb.stream") 설정
ConvertStream.Mode =3
ConvertStream.Charset="GB2312"
Request.TotalBytes<1이면 Sub를 종료합니다.
'dStart = CDbl(시간)
'첫 번째 경계 찾기
iStart = 검색(Upload_Stream, ChrB(13)&ChrB(10), 1)
'경계 문자열을 가져옵니다
경계 = subString(1, iStart-1, false)
'끝 경계가 아니면 반복됩니다.
StrComp(subString(iStart, 2, false),ChrB(13)&ChrB(10))=0 동안 수행합니다.
iStart = iStart+2
'양식 항목 정보 헤더 가져오기
진실할 때 해라
iEnd = 검색(Upload_Stream, ChrB(13)&ChrB(10), iStart)
'정보 헤더 분해
line = subString(iStart, iEnd-iStart, true)
'위치 이동
iStart = iEnd+2
Line=""이면 종료합니다.
pos = instr(라인,":")
pos>0이면
if StrComp(left(Line,pos-1),"Content-Disposition",1)=0 then
'양식 항목 이름을 가져옵니다
FieldName = ExtractValue(라인,위치+1,"이름")
'파일 이름 가져오기
FileName = ExtractValue(Line,pos+1,"파일 이름")
'파일 경로 삭제
파일 이름 = Mid(파일 이름,InStrRev(파일 이름, "")+1)
elseif StrComp(left(Line,pos-1),"Content-Type",1)=0 then
'파일 형식 가져오기
ContentType = 트림(mid(Line,pos+1))
종료하면
종료하면
고리
'양식 항목 내용 가져오기
FileName<>""이면
'새 파일 내용
theFile = 새 FileInfo 설정
theFile.Init 파일 이름, 콘텐츠 유형
'파일 스트림 내용을 파일 스트림으로 이동
MoveData Upload_Stream, theFile.Stream, iStart
'업로드 데이터가 파일 스트림으로 직접 전송되므로 파일 저장 시간을 줄일 수 있습니다.
iEnd = 검색(theFile.Stream, 경계, 1)
'후속 데이터를 워크플로로 이동
MoveData theFile.Stream, Upload_Stream, iEnd-2
'
FFile.add 필드 이름, theFile
'위치 이동
iStart = iStart+2+LenB(경계)
또 다른
'경계를 찾아라
iEnd = 검색(Upload_Stream, 경계, iStart)
'양식 항목 내용 가져오기
ItemValue = subString(iStart, iEnd-2-iStart, true)
'
FForm.Exists(FieldName)인 경우
FForm.Item(FieldName) = FForm.Item(FieldName) & "," & ItemValue
또 다른
FForm.Add FieldName, ItemValue
종료하면
'위치 이동
iStart = iEnd+LenB(경계)
종료하면
고리
'Response.Write "구문 분석 시간:" & FormatNumber((CDbl(Time)-dStart)*24*60*60,-1,-1) & "<br>"
End Sub
개인 함수 검색(src, str, theStart)
iStart = theStart
위치=0
pos=0인 동안 수행
'길이가 길지 않으니 한 편씩 읽어보세요.
src.Size<(iStart+lenb(str)-1)이면 ReadChunk src
'메모리 요구 사항을 줄일 수 있는 약 64K의 데이터를 가져옵니다.
src.Position = iStart-1
buf = src.Read
'경계 감지
위치=InStrB(buf,str)
'찾을 수 없으면 뒤로 이동
pos=0이면 iStart = iStart+LenB(buf)-LenB(str)+1
고리
검색 = iStart+pos-1
기능 종료
비공개 하위 MoveData(Src, Dest, theStart)
Src.Position = theStart-1
목적지.위치 = 목적지.크기
원본.대상으로 복사
Src.Position = theStart-1
Src.SetEOS
서브 끝
개인 함수 ExtractValue(라인, 위치, 이름)
희미한 t, p
추출값 = ""
t = 이름 + "="""
p = instr(위치,라인,티)
p>0이면
n1 = p+len(t)
n2 = instr(n1,line,"""")
n2>n1이면 ExtractValue = mid(line,n1,n2-n1)
종료하면
end 함수
개인 함수 subString(theStart,theLen, ConvertToUnicode)
만약 theLen>0이면
'길이가 충분하지 않으면 데이터를 읽습니다.
Upload_Stream.Size<theStart+theLen-1이면 ReadChunk Upload_Stream
Upload_Stream.Position=theStart-1
바이너리 =Upload_Stream.Read(theLen)
만약 ConvertToUnicode라면
ConvertStream.Type = 1
ConvertStream.Open
ConvertStream.Write 바이너리
ConvertStream.Position = 0
ConvertStream.Type = 2
하위 문자열 = ConvertStream.ReadText
ConvertStream.Close
또 다른
하위 문자열 = midB(바이너리,1)
종료하면
또 다른
하위 문자열 = ""
종료하면
기능 종료
비공개 하위 ReadChunk(src)
'블록을 읽으십시오. 한 번에 64K를 읽으면 데이터 양이 너무 많을 때 메모리 오버플로를 방지할 수 있습니다.
Response.IsClientConnected = false인 경우 "네트워크 연결이 중단되었습니다" 발생
바이트읽기 = 65536
src.Position = src.Size
src.쓰기 요청.BinaryRead(BytesRead)
서브 끝
'예외정보
비공개 구독료 인상(메시지)
Err.Raise vbObjectError, "QuickUpload", 메시지
End Sub
Private Sub Class_Terminate
form.RemoveAll
파일.모두 제거
양식 설정 = 없음
파일 설정 = 없음
Upload_Stream.close
Upload_Stream=nothing 설정
ConvertStream.Close
setConvertStream=아무것도 없음
End Sub
End 클래스
클래스 FileInfo
비공개 FFileName, FFileType, FFileStart, FFileSize, FStream
속성은 FileName을 얻습니다.
파일 이름 = F파일 이름
끝 속성
속성은 FileType을 얻습니다.
파일 유형 = FFileType
끝 속성
속성은 FileSize를 얻습니다.
파일 크기 = FStream.Size
끝 속성
속성 getStream
setStream = FStream
끝 속성
공개 하위 초기화(AFileName, AFileType)
FFileName = AFileName
FFileType = AFileType
서브 끝
공용 함수 SaveAs(FullPath)
희미한 박사,ErrorChar,i
'dStart = CDbl(시간)
다른 이름으로 저장=1
Trim(fullpath)="" 또는 right(fullpath,1)="/"인 경우 함수를 종료합니다.
오류 발생 시 다음 재개
FStream.SaveToFile FullPath,2
if Err.Number>0 then Response.Write "데이터 저장 오류:" & Err.Description & "<br>"
다른 이름으로 저장=0
'Response.Write "시간 절약:" & FormatNumber((CDbl(Time)-dStart)*24*60*60,-1,-1) & "<br>"
함수 종료
비공개 하위 클래스_초기화
FStream=CreateObject("Adodb.Stream") 설정
FStream.mode=3
FStream.type=1
FStream.open
서브 끝
비공개 하위 클래스_종료
FStream.Close
FStream=아무것도 설정하지 않음
서브 끝
수업 종료