Em termos de velocidade de decodificação, o Huajing 2.0 já é muito alto, mas ainda apresenta os dois problemas a seguir:
1. Use Data_5xsoft.Write Request.BinaryRead(Request.TotalBytes) para ler todos os dados de uma vez e use RequestData =Data_5xsoft.Read para obter todos os dados de uma vez. Quando os dados carregados forem muito grandes, o upload falhará devido. para memória insuficiente. Isso deve ser Use o método de leitura segmentada.
2. Ao salvar dados, você precisa primeiro copiá-los do Data_5xsoft para um fluxo temporário. Ao salvar um arquivo grande, são necessários o dobro dos recursos de armazenamento. Quando testado em um estado independente, pode-se descobrir que o tempo de economia aumenta. drasticamente com o tamanho do arquivo, excedendo até mesmo o tempo de upload e de decodificação.
A classe que escrevi usa o método de leitura bloco por bloco durante o processo de decodificação (nota: o tamanho do bloco não é proporcional à velocidade. Testes de máquina única mostram que blocos de 64K são muito mais rápidos que blocos de 1M) para resolver o problema 1 . e, ao mesmo tempo, usamos o método de gravação de dados comuns no fluxo de trabalho e gravação do conteúdo do arquivo diretamente no próprio fluxo do arquivo para resolver o problema 2.
O código é o seguinte, o uso é semelhante ao Huajing:
Server.ScriptTimeOut = 600
Class QuickUpload
FForm privado, FFile, Upload_Stream, ConvertStream
propriedade obter formulário
setForm = FForm
propriedade final
propriedade obter arquivo
setArquivo = FFArquivo
propriedade final
Subclasse Privada_Initialize
dim iStart, iEnd, limite, FieldName, FileName, ContentType, ItemValue, theFile, LineEnd
definir FForm=CreateObject("Scripting.Dictionary")
definir FFile=CreateObject("Scripting.Dictionary")
definir Upload_Stream=CreateObject("Adodb.Stream")
Upload_Stream.mode=3
Upload_Stream.type=1
Upload_Stream.open
definir ConvertStream = Server.CreateObject("adodb.stream")
ConvertStream.Mode =3
ConvertStream.Charset="GB2312"
se Request.TotalBytes<1 então saia do Sub
'dInício = CDbl(Tempo)
'Encontre o primeiro limite
iStart = Pesquisa(Upload_Stream, ChrB(13)&ChrB(10), 1)
'Obtém a string limite
limite = subString(1, iStart-1, false)
'Se não for o limite final, então ele fará um loop
faça enquanto StrComp(subString(iStart, 2, false),ChrB(13)&ChrB(10))=0
iIniciar = iIniciar+2
'Obtém o cabeçalho de informações do item do formulário
faça enquanto for verdade
iEnd = Pesquisa(Upload_Stream, ChrB(13)&ChrB(10), iStart)
'Decompor cabeçalho de informações
linha = subString(iStart, iEnd-iStart, true)
'Mover posição
iInício = iFim+2
se Line="" então Sair faça
pos = instr(linha,":")
se pos>0 então
se StrComp(left(Line,pos-1),"Content-Disposition",1)=0 então
'Obtém o nome do item do formulário
NomeCampo = ExtrairValor(Linha,pos+1,"nome")
'Obtém o nome do arquivo
NomeArquivo = ExtrairValor(Linha,pos+1,"nomearquivo")
'Excluir caminho do arquivo
NomeArquivo = Mid(NomeArquivo,InStrRev(NomeArquivo, "")+1)
elseif StrComp(left(Line,pos-1),"Content-Type",1)=0 então
'Obtém o tipo de arquivo
ContentType = trim(mid(Linha,pos+1))
terminar se
terminar se
laço
'Obtém o conteúdo do item do formulário
se NomeArquivo<>"" então
'Novo conteúdo do arquivo
defina theFile = new FileInfo
theFile.Init Nome do arquivo, ContentType
'Move o conteúdo do stream de arquivos para o stream de arquivos
MoveData Upload_Stream, theFile.Stream, iStart
'Os dados de upload são transferidos diretamente para o fluxo de arquivos, o que pode reduzir o tempo de armazenamento de arquivos
iEnd = Pesquisar(theFile.Stream, limite, 1)
'Mova os dados subsequentes para o fluxo de trabalho
MoveData theFile.Stream, Upload_Stream, iEnd-2
'
FFile.add FieldName, oArquivo
'Mover posição
iStart = iStart+2+LenB(limite)
outro
'Encontre limites
iEnd = Search(Upload_Stream, limite, iStart)
'Obtém o conteúdo do item do formulário
ItemValue = subString(iStart, iEnd-2-iStart, verdadeiro)
'
se FForm.Exists(FieldName) então
FForm.Item(NomeCampo) = FForm.Item(NomeCampo) & "," & ItemValue
outro
FForm.Add FieldName, ItemValue
terminar se
'Mover posição
iStart = iEnd+LenB(limite)
terminar se
laço
'Response.Write "tempo de análise:" & FormatNumber((CDbl(Time)-dStart)*24*60*60,-1,-1) & "<br>"
End Sub
Private Function Search (src, str, theStart)
iStart = theStart
posição = 0
faça enquanto pos=0
'O comprimento não é longo o suficiente, leia um pedaço
se src.Size<(iStart+lenb(str)-1) então ReadChunk src
'Obtenha um dado, cerca de 64K, que pode reduzir os requisitos de memória
src.Position = iStart-1
buf = src.Leitura
'Detectar limites
pos=InStrB(buf,str)
'Se não for encontrado, retroceda
se pos=0 então iStart = iStart+LenB(buf)-LenB(str)+1
laço
Pesquisa = iStart+pos-1
Função final
sub privado MoveData(Src, Dest, theStart)
Src.Position = theStart-1
Posição de destino = Tamanho de destino
Src.CopyTo destino
Src.Position = theStart-1
Src.SetEOS
final sub
função privada ExtractValue(linha,pos,nome)
escurecer t, p
ExtrairValor = ""
t = nome + "="""
p = instr(pos,linha,t)
se p>0 então
n1 = p+len(t)
n2 = instr(n1,linha,"""")
se n2>n1 então ExtractValue = mid(linha,n1,n2-n1)
terminar se
função final
Função privada subString(theStart,theLen, ConvertToUnicode)
se Len>0 então
'Quando o comprimento não for suficiente, leia um dado
se Upload_Stream.Size<theStart+theLen-1 então ReadChunk Upload_Stream
Upload_Stream.Position=theStart-1
Binário =Upload_Stream.Read(theLen)
se ConvertToUnicode então
ConvertStream.Type = 1
ConvertStream.Open
ConvertStream.Write Binário
ConvertStream.Position = 0
ConvertStream.Type = 2
subString = ConvertStream.ReadText
ConvertStream.Fechar
outro
subString = midB (binário, 1)
terminar se
outro
subString = ""
terminar se
Função final
SubReadChunk Privado(src)
'Leia um bloco, lendo 64K por vez, você pode evitar o estouro de memória quando a quantidade de dados for muito grande
se Response.IsClientConnected = false então aumente "Conexão de rede interrompida"
Bytes lidos = 65536
src.Position = src.Size
src.Write Request.BinaryRead(BytesRead)
Finalizar sub
'Informações de exceção
Sub-aumento privado (mensagem)
Err.Raise vbObjectError, "QuickUpload", Mensagem
Fim Sub
Privado Subclasse_Terminate
formulário.Remover tudo
arquivo.Remover tudo
definir formulário = nada
definir arquivo = nada
Upload_Stream.fechar
definir Upload_Stream = nada
ConvertStream.Fechar
setConvertStream = nada
Fim Sub
Fim Classe
Classe FileInfo
FFileName privado, FFileType, FFileStart, FFileSize, FStream
propriedade obter nome do arquivo
NomeArquivo = FFileName
propriedade final
propriedade obter FileType
Tipo de arquivo = FFileType
propriedade final
propriedade obter FileSize
Tamanho do arquivo = FStream.Size
propriedade final
propriedade getStream
setStream =FStream
propriedade final
Sub Init público (AFileName, AFileType)
FFileName = AFileName
FFileType = AFileType
Finalizar sub
Função pública SaveAs(FullPath)
dim dr,ErrorChar,i
'dInício = CDbl(Tempo)
Salvar como=1
se trim(fullpath)="" ou right(fullpath,1)="/" então saia da função
Em caso de erro, retomar o próximo
FStream.SaveToFile FullPath,2
se Err.Number>0 então Response.Write "Erro ao salvar dados:" & Err.Description & "<br>"
Salvar como=0
'Response.Write "economize tempo:" & FormatNumber((CDbl(Time)-dStart)*24*60*60,-1,-1) & "<br>"
função final
Subclasse Privada_Initialize
definir FStream=CreateObject("Adodb.Stream")
FStream.mode=3
FStream.type=1
Fstream.open
final sub
Subclasse Privada_Terminate
FStream.Fechar
definir FStream = nada
final sub
Fim da aula