ASP Component-less upload

Source: Internet
Author: User
Tags one more line

File Upload Component: Upload. asp
<%
Dim stream1, stream2, istart, iend, filename
Istart = 1
Vbenter = CHR (13) & CHR (10)

Function getvalue (fstr, Foro, paths) 'fstr is the name of the receiver, Foro Boolean false is the file upload, true is a common field, and path is the storage path of the uploaded file
If Foro then
Getvalue = ""
Istart = instring (istart, fstr)

Istart = istart + Len (fstr) + 5
Iend = instring (istart, vbenter + "-----------------------------")
If istart> 5 + Len (fstr) then
Getvalue = substring (istart, iend-istart)

Else
Getvalue = ""
End if
Else
 
Istart = instring (istart, fstr)
Istart = istart + Len (fstr) + 13
Iend = instring (istart, vbenter)-1

Filename = substring (istart, iend-istart)
Filename = getfilename (filename)
'Checkfileext (fstr) '''''''''''''''''''''''''''''''''''''''' '''''''''''''''
Istart = instring (iend, vbenter + vbenter) + 3
Iend = instring (istart, vbenter + "-----------------------------")
Filestart = istart
Filesize = iend-istart-1
Objstream. Position = filestart
Set Sf = server. Createobject ("ADODB. Stream ")
SF. mode = 3
SF. type = 1
SF. Open
Objstream. copyto SF, filesize

If filename <> "" then
Set Rf = server. Createobject ("scripting. FileSystemObject ")
I = 0
Fn = filename
While RF. fileexists (server. mappath (paths + FN ))

Fn = CSTR (I) + filename
I = I + 1
Wend
Filename = FN
SF. savetofile server. mappath (paths + filename), 2
End if
Getvalue = filename
End if
End Function

Private function getfilename (fullpath)
If fullpath <> "" then
Getfilename = mid (fullpath, limit Rev (fullpath, "/") + 1)
Else
Getfilename = ""
End if
End Function

Function instring (thestart, varstr)
Dim I, j, BT, thelen, STR
Instring = 0
STR = tobyte (varstr)
Thelen = lenb (STR)
For I = thestart to objstream. Size-thelen
If I> objstream. Size then exit function

Objstream. Position = I-1
If ASCB (objstream. Read (1) = ASCB (midb (STR, 1) then
Instring = I
For J = 2 to thelen
If objstream. EOS then
Instring = 0
Exit
End if
If ASCB (objstream. Read (1) <> ASCB (midb (STR, J, 1) then
Instring = 0
Exit
End if
Next
If instring <> 0 Then exit function
End if
Next
End Function

Function tobyte (STR)
Dim I, icode, C, ilow, ihigh
Tobyte = ""
For I = 1 to Len (STR)
C = mid (STR, I, 1)
Icode = ASC (c)
If icode <0 then icode = icode + 65535
If icode> 255 then
Ilow = left (hex (ASC (c), 2)
Ihigh = right (hex (ASC (c), 2)
Tobyte = tobyte & chrb ("& H" & ilow) & chrb ("& H" & ihigh)
Else
Tobyte = tobyte & chrb (ASCB (c ))
End if
Next
End Function

Function substring (thestart, thelen)
Dim I, C, stemp
Objstream. Position = theStart-1
Stemp = ""
For I = 1 to thelen
If objstream. EOS then exit
C = ASCB (objstream. Read (1 ))
If C & gt; 127 then
If objstream. EOS then exit
Stemp = stemp & CHR (ASCW (chrb (ASCB (objstream. Read (1) & chrb (c )))
I = I + 1
Else
Stemp = stemp & CHR (c)
End if
Next
Substring = stemp
End Function
%>

1. html
<HTML>
<Head>
<Title> upload images and text together </title>
</Head>
<Style>
Body {font-size: 12px ;}
</Style>
<Body>
<Form action = "uploadfile. asp" method = "Post" enctype = "multipart/form-Data" name = "form1">
File Path <input type = "file" name = "filepath"> <br>
& Nbsp; Title <input type = "text" name = "FILENAME"> <br>
<Input type = "Submit" value = "Submit">
</Form>
</Body>
</Html>

Uploadfile. asp
<! -- # Include file = "Upload. asp" -->
<%
If request. totalbytes> 0 then
Set objstream = server. Createobject ("ADODB. Stream ")
Objstream. mode = 3
Objstream. type = 1
Objstream. Open
Objstream. Write Request. binaryread (request. totalbytes)

Path = getvalue ("filepath", false, "PIC/") 'pic is the name of the next folder in the current directory. You can also change it to ../PIC, that is, the PIC folder in the upper directory.
Name = getvalue ("FILENAME", true ,"")
Response. Write "file name:" & Path & "title:" & name
'Response. End

End if
%>

Source: Baoyu blog

I. No ComponentsUploadPrinciple
Let me describe it with an instance at 1.1. The client HTML is as follows. To browseUploadAttachment, we use the <input type = "file"> element, but be sure to set the enctype attribute of form to "multipart/form-Data ":

<Form method = "Post" Action = "upload.ASP"Enctype =" multipart/form-Data ">
<Label>
<Input type = "file" name = "file1"/>
</Label>
<Br/>
<Input type = "text" name = "FILENAME" value = "Default FILENAME"/>
<Br/>
<Input type = "Submit" value = "Submit"/>
<Input type = "reset" value = "reset"/>
</Form>

In the backgroundASPIn the program, it is very easy to get the ASCII data submitted by the form before. However, if you want to obtainUploadYou must use the binaryread method of the request object to read the object. The binaryread method reads the specified number of bytes of the current input stream in binary format. It is worth noting that once the binaryread method is used, the request. Form or request. querystring set cannot be used any more. Combined with the totalbytes attribute of the request object, all the data submitted by the form can be converted to binary, but the data is encoded. First, let's take a look at how the data is encoded, and whether there are any rules to follow. In the code, we convert binary data read by binaryread into text and output it, upload.ASP(Note that this example is notUploadLarge files, otherwise the browser may die ):
<%
Dim bidata, postdata
Size = request. totalbytes
Bidata = request. binaryread (size)
Postdata = binarytostring (bidata, size)
Response. Write "<PRE>" & postdata & "</PRE>" 'uses pre, which is in the original output format.
'Use recordset to convert binary data into text
Function binarytostring (bidata, size)
Const adlongvarchar = 201
Set rs = Createobject ("ADODB. recordset ")
Rs. Fields. APPEND "mbinary", adlongvarchar, size
Rs. Open
Rs. addnew
RS ("mbinary"). AppendChunk (bidata)
Rs. Update
Binarytostring = RS ("mbinary"). Value
Rs. Close
End Function
%>

For simplicity,UploadA simplest text file (G:/homepage.txt, content is "Baoyu: http://www.webuc.net") to test, text box filename retain the default value "Default FILENAME", submit to see the output result:

----------------------------- 7d429871607fe
Content-Disposition: Form-data; name = "file1"; filename = "G:/homepage.txt"
Content-Type: text/plain
Baoyu: http://www.webuc.net
----------------------------- 7d429871607fe
Content-Disposition: Form-data; name = "FILENAME"
Default filename
----------------------------- 7d429871607fe --

It can be seen that for the items in the form, the boundary "--------------------------- 7d429871607fe" is used to separate them into one piece. Each piece has some description information at the beginning, for example: content-Disposition: Form-data; name = "FILENAME". In the description information, the name of the form item can be known through name = "FILENAME. If there is content such as filename = "G:/homepage.txt", it meansUploadFile, if it isUploadThe description will contain one more line of Content-Type: text/plain to describe the Content-Type of the file. Description information and subject information are separated by line breaks.

Well, it's basically clear. Based on this rule, we know how to separate the data and then process the separated data, but we almost ignored a problem, is the boundary value ("----------------------------- 7d429871607fe" in the above example) How to know? Each timeUploadThis boundary value is different, but it's okay.ASPRequest. servervariables ("http_content_type"). For example, the content of http_content_type in the preceding example is: "multipart/form-data; boundary = ------------------------- 7d429871607fe, we can not only judge whether the client's form uses enctype = "multipart/form-Data" (if it is not used, then there is no need to execute it below ), you can also obtain boundary = --------------------------- 7d429871607fe. (Note: The obtained boundary value is less "--" than the beginning of the boundary value. It is best to add it .)

As for how to analyze the data, I will not go into details. It is nothing more than using functions such as instr and mid to separate the data we want.

Ii. multipartUpload, Recording progress
To reflect the progress bar in real time, we need to know how much data the current server has obtained in real time? Let's look at our implementation.UploadThe process is implemented through request. binaryread (request. totalbytes). During the request process, we cannot know how much data the current server has obtained. Therefore, we can only use a work ing method. If we can split the obtained data into one pieceUploadWe can calculate the current number of blocks.UploadHow big is it! That is to say, if I use 1 KUploadThe input stream of 1 MB is divided into 1024 pieces for retrieval. For example, if I have obtained 100 pieces, it indicates that the currentUpload100 K. When I proposed the multipart method, many people thought it was incredible because they ignored the binaryread method to read not only the specified size, but also the specified size.

Write an example to verify the integrity of the multipart read.UploadLarge files, otherwise the browser may die ):

<%
Dim bidata, postdata, totalbytes, chunkbytes
Chunkbytes = 1*1024 'block size is 1 K
Totalbytes = request. totalbytes 'total size
Postdata = "" 'data converted to text type
Readedbytes = 0' Initialization is 0
'Multipart read
Do While readedbytes <totalbytes
Bidata = request. binaryread (chunkbytes) 'current Block
Postdata = postdata & binarytostring (bidata, chunkbytes) 'converts the current block into text and concatenates it.
Readedbytes = readedbytes + chunkbytes record read size
If readedbytes> totalbytes then readedbytes = totalbytes
Loop
Response. Write "<PRE>" & postdata & "</PRE>" 'uses pre, which is in the original output format.
'Convert binary into text
Function binarytostring (bidata, size)
Const adlongvarchar = 201
Set rs = Createobject ("ADODB. recordset ")
Rs. Fields. APPEND "mbinary", adlongvarchar, size
Rs. Open
Rs. addnew
RS ("mbinary"). AppendChunk (bidata)
Rs. Update
Binarytostring = RS ("mbinary"). Value
Rs. Close
End Function
%>

TestUploadThe output of the text file just now proves that the content read in this part is complete. In the while loop, we can record the current status to the application in each loop, then we can access the application to dynamically obtainUploadProgress bar.

In the preceding example, strings are concatenated. To splice binary data, you can use the write method of the ADODB. Stream object. The sample code is as follows:

Set bsourcedata = Createobject ("ADODB. Stream ")
Bsourcedata. Open
Bsourcedata. type = 1' binary
Do While readedbytes <totalbytes
Bidata = request. binaryread (chunkbytes)
Bsourcedata. Write bidata directly use the write method to write the current file stream to bsourcedata
Readedbytes = readedbytes + chunkbytes
If readedbytes> totalbytes then readedbytes = totalbytes
Application ("readedbytes") = readedbytes
Loop

Iii. SaveUploadFile
Use request. binaryread to obtain the submitted data and separate the data.UploadAfter the file is saved, the storage method varies depending on the Data Type:

For binary data, you can directly use the savetofile method of the ADODB. Stream object to save the binary stream as a file.
You can use the write method of the textstream object to save text data to a file.
Text Data and binary data can be easily converted to each other.UploadFor small files, there is basically no difference between the two. However, there are some differences between the two methods. For the ADODB. Stream object, all data must be fully loaded before it can be saved as a file.UploadLarge files occupy a lot of memory. For textstream objects, you can write a part of the file once and write it multiple times after the file is created. This advantage is that it does not occupy the server memory space, based on the data block acquisition principle analyzed above, we can obtain each blockUploadWrite the data to the file. I have performed tests on this machine.UploadThe first method of memory usage for a 200-MB file keeps increasing. At last, the system directly prompts that the computer's virtual memory is insufficient. The most hateful way is that even if the progress bar indicates that the file hasUploadBut the final file is not saved. The latter method is used,UploadThe memory remains unchanged.

Iv. Unsolved Problems
I saw bestcomy describe him on the blog.ASP. NetUploadThe component can be independent of Sever. setTimeout, whileASPI failed to do it.UploadFor large files, you can only set server. setTimeout to a large value. I wonder if there is any better solution.

If we use the write method of the textstream object when saving the file, if the userUploadThe file transmission is interrupted.UploadThe part of the file is still in, if you can resume the upload. The key issue is that although the request. binaryread method can be used for multipart reading, it cannot skip a certain segment of reading!

V. Conclusion
The principle is basically clear, but the actual code is much more complicated than this. There are many issues to consider. The most troublesome part is to analyze the data. For each piece of data, whether the analysis is a description, a form project, orUploadFile, whether the file has beenUploadEnd ......

Based on the above description, you can also develop your own powerful component-lessUploadComponent. I think more people only care about code, instead of writing it by themselves. Maybe there is no time, maybe the level is not enough, and more is just a habit ...... I have seen too many technical documents on csdn-a description, followed by code. Give you a code, maybe you don't want to think about why or use it directly. When you encounter a similar problem next time, I still don't know why, I hope this article will allow more people to learn something. The most important thing is "Understanding!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.