デコード速度の点では、Huajing 2.0 はすでに非常に高速ですが、次の 2 つの問題がまだあります。
1. Data_5xsoft.Write Request.BinaryRead(Request.TotalBytes) を使用してすべてのデータを一度に読み取り、RequestData =Data_5xsoft.Read を使用してすべてのデータを一度に取得します。アップロードされたデータが大きすぎると、アップロードが失敗します。メモリが不足している場合は、セグメント読み取り方式を使用する必要があります。
2. データを保存する場合、最初に Data_5xsoft から一時ストリームにコピーする必要があります。大きなファイルを保存する場合、2 倍のストレージ リソースが必要になります。スタンドアロン状態でテストすると、保存時間が長くなることがわかります。ファイルサイズが大幅に増加し、アップロード時間やデコード時間を超える場合もあります。
私が作成したクラスでは、デコード プロセス中にブロックごとに読み取る方法を使用しています (注: ブロックのサイズは速度に比例しません。単一マシンのテストでは、64K ブロックの方が 1M ブロックよりはるかに高速であることが示されています)。問題 1 を解決します。 . 同時に、通常のデータをワークフローに書き込み、ファイルのコンテンツをファイル自体のストリームに直接書き込む方法を使用して、問題 2 を解決します。
コードは次のとおりです。使用方法は Huajing と似ています。
Server.ScriptTimeOut = 600
Class QuickUpload
プライベート FForm、FFile、Upload_Stream、ConvertStream
プロパティ取得フォーム
setForm = FForm
終了プロパティ
プロパティ取得ファイル
setFile = FFile
終了プロパティ
プライベートサブクラス_初期化
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")
アップロード_ストリーム.モード=3
アップロード_ストリーム.タイプ=1
アップロード_ストリーム.オープン
set ConvertStream = Server.CreateObject("adodb.stream")
ConvertStream.Mode =3
ConvertStream.Charset="GB2312"
Request.TotalBytes<1 の場合は Sub を終了します
'dStart = CDbl(時間)
'最初の境界を見つけます
iStart = Search(Upload_Stream, ChrB(13)&ChrB(10), 1)
'境界文字列を取得する
境界 = subString(1, iStart-1, false)
'終了境界でない場合はループします
StrComp(subString(iStart, 2, false),ChrB(13)&ChrB(10))=0 の間実行します
iスタート = iスタート+2
'フォーム項目情報ヘッダーを取得
真実ながら行う
iEnd = Search(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
'フォーム項目名を取得
フィールド名 = 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))
終了する場合
終了する場合
ループ
'フォーム項目の内容を取得する
if FileName<>"" then
'新しいファイルの内容
ファイル = 新しいファイル情報を設定します
theFile.Init ファイル名、ContentType
' ファイル ストリームのコンテンツをファイル ストリームに移動します
MoveData Upload_Stream、theFile.Stream、iStart
'アップロード データはファイル ストリームに直接転送されるため、ファイルの保存時間を短縮できます。
iEnd = Search(theFile.Stream, 境界, 1)
'後続のデータをワークフローに移動します
MoveData theFile.Stream、Upload_Stream、iEnd-2
'
FFile.add フィールド名、ファイル
'位置を移動
iStart = iStart+2+LenB(境界)
それ以外
'境界線を見つける
iEnd = 検索(Upload_Stream、境界、iStart)
'フォーム項目の内容を取得する
ItemValue = subString(iStart, iEnd-2-iStart, true)
'
FForm.Exists(フィールド名) の場合
FForm.Item(フィールド名) = FForm.Item(フィールド名) & "," & itemValue
それ以外
FForm.Add フィールド名、項目値
終了する場合
'位置を移動
iStart = iEnd+LenB(境界)
終了する場合
ループ
'Response.Write "解析時間:" & FormatNumber((CDbl(Time)-dStart)*24*60*60,-1,-1) & "<br>"
End Sub
プライベート関数検索(src, str, theStart)
iStart = スタート
pos=0
pos=0 の間行う
「長さが足りないので、一枚読んでください」
if src.Size<(iStart+lenb(str)-1) then ReadChunk src
'約 64K のデータを取得します。これにより、メモリ要件が軽減されます。
src.Position = iStart-1
buf = src.Read
'境界を検出する
pos=InStrB(buf,str)
'見つからない場合は後戻りします
pos=0 の場合、iStart = iStart+LenB(buf)-LenB(str)+1
ループ
検索 = iStart+pos-1
終了機能
プライベート サブ MoveData(Src, Dest, theStart)
Src.Position = theStart-1
宛先位置 = 宛先サイズ
Src.CopyTo dest
Src.Position = theStart-1
Src.SetEOS
エンドサブ
プライベート関数 ExtractValue(line,pos,name)
薄暗い、p
ExtractValue = ""
t = 名前 + "="""
p = instr(pos,line,t)
p>0 の場合
n1 = p+len(t)
n2 = instr(n1,line,"""")
n2>n1 の場合、ExtractValue = Mid(line,n1,n2-n1)
終了する場合
end function
プライベート関数 subString(theStart,theLen,ConvertToUnicode)
Len>0 の場合
'長さが足りない場合はデータを読み込む
if Upload_Stream.Size<theStart+theLen-1 then 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
subString = ConvertStream.ReadText
ConvertStream.Close
それ以外
subString = midB(バイナリ,1)
終了する場合
それ以外
部分文字列 = ""
終了する場合
終了機能
プライベート サブ ReadChunk(src)
'ブロックを読み取り、一度に64Kを読み取ることで、データ量が多すぎる場合のメモリオーバーフローを防ぐことができます
Response.IsClientConnected = false の場合、「ネットワーク接続が中断されました」を発生させます
読み取りバイト数 = 65536
src.Position = src.Size
src.Write Request.BinaryRead(BytesRead)
エンドサブ
'例外情報
プライベートサブレイズ(メッセージ)
Err.Raise vbObjectError、「QuickUpload」、メッセージ
End Sub
Private Sub Class_Terminate
form.RemoveAll
file.RemoveAll
フォーム=何も設定しない
ファイル=何も設定しない
Upload_Stream.close
Upload_Stream=何も設定しない
ConvertStream.Close
setConvertStream=なし
End Sub
End Class
Class FileInfo
プライベート FFileName、FFileType、FFileStart、FFileSize、FStream
プロパティ取得ファイル名
ファイル名 = Fファイル名
終了プロパティ
プロパティ取得ファイルタイプ
ファイルタイプ = Fファイルタイプ
終了プロパティ
プロパティ取得ファイルサイズ
ファイルサイズ = FStream.サイズ
終了プロパティ
プロパティ
setStream = FStream
終了プロパティ
Public Sub Init(AFileName, AFileType)
Fファイル名 = Aファイル名
FFileType = AFileType
エンドサブ
パブリック関数 SaveAs(FullPath)
dim dr、ErrorChar、i
'dStart = CDbl(時間)
名前を付けて保存=1
trim(fullpath)="" または right(fullpath,1)="/" の場合、関数を終了します
エラー時は次へ再開
FStream.SaveToFile フルパス、2
if Err.Number>0 then Response.Write "データ保存エラー:" & Err.Description & "<br>"
名前を付けて保存=0
'Response.Write "保存時間:" & FormatNumber((CDbl(Time)-dStart)*24*60*60,-1,-1) & "<br>"
終了関数
プライベートサブクラス_初期化
set FStream=CreateObject("Adodb.Stream")
FStream.mode=3
FStream.type=1
FStream.open
エンドサブ
プライベートサブクラス_Terminate
FStream.Close
FStream=何も設定しない
エンドサブ
終了クラス