[Top] ASP no-component upload progress bar Solution

Source: Internet
Author: User
Tags server memory
I. Principle of component-less upload
Let me describe it with an instance at 1.1. The client HTML is as follows. To browse and upload attachments, 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>

ASP in the background Program . However, to obtain the uploaded file, you must use the binaryread method of the request 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. Code In the code, we convert the binary data read by binaryread into text and output it to the background upload. ASP (note that this example does not upload large 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>" pre, original output format
Convert binary data into text using recordset
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, upload the simplest text file (G: \ homepage.txt, the content is "Baoyu: http://www.webuc.net";) to test, text box filename to retain the default value "Default FILENAME ", submit and view 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 indicates that it is an uploaded file. If it is an uploaded file, in this case, plain ontent-type: text/plain is used 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? The boundary value for each upload is different. Fortunately, you can use the request in ASP. 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 preceding 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. multipart upload, 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 back at the upload process through request. binaryread (request. totalbytes). During the request process, we cannot know how much data the current server has obtained. So we can only use a work ing method. If we can split the obtained data into one piece, then we can calculate the size of the uploaded part based on the number of uploaded parts! That is to say, if I use 1 K for 1 piece, the input stream of 1 MB will be divided into 1024 pieces for acquisition. For example, if I have obtained 100 pieces, it indicates that 100 K has been uploaded. 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 block reading. Based on the example above (note that this example does not upload large files, otherwise the browser may die ):

<%
dim bidata, postdata, totalbytes, chunkbytes
chunkbytes = 1*1024 block size is 1 k
totalbytes = request. total size of totalbytes
postdata = "" data converted to text type
readedbytes = 0 initialized to 0
block read
do while readedbytes bidata = request. binaryread (chunkbytes) Current block
postdata = postdata & binarytostring (bidata, chunkbytes) convert the current block to text and splice it.
readedbytes = readedbytes + chunkbytes record read size
If readedbytes> totalbytes then readedbytes = totalbytes
loop
response. write "

" & postdata & "
" Use pre, original output format
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
%>

Test the upload of the text file. The output result shows that the multipart read content is complete. In the while loop, we can record the current status to the application during each loop, then we can access the application to dynamically obtain the upload progress 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

3. Save uploaded files
Use request. binaryread to obtain the submitted data. After the uploaded file is separated, 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. For uploading small files, there is basically no difference between the two. However, there are some differences between the two methods, for ADODB. the stream object can be saved as a file only after all the data is loaded. Therefore, if you use this method to upload large files, the memory usage will be high. For textstream objects, after a file is created, you can write a part of the file at a time and write it multiple times. The advantage is that it does not occupy the server memory space. In combination with the data block acquisition principle analyzed above, we can write each piece of uploaded data to the file. I have tried to upload a file of more than 200 MB on the local machine, and the memory usage in the first method has been increasing. In the end, I am prompted that the computer's virtual memory is insufficient, the most hateful thing is that the final file is not saved even if the progress bar indicates that the file has been uploaded. Using the latter method, the memory remains unchanged during the upload process.

Iv. Unsolved Problems
On the blog page, I saw bestcomy describe that his Asp.net upload component can be used with Sever. setTimeout is irrelevant, but I cannot do it in ASP. for uploading large files, you only need to upload the server. set 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 file transmission is interrupted during the upload, the uploaded part of the file is still in progress, if resumable upload is supported. 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, do you want to analyze whether it is a description, a form project, an uploaded file, or whether the file has been uploaded ......

based on the preceding description, you can develop a powerful component-less Upload Component. 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, you still don't know why, I hope this article will help more people learn more
articles : webmaster sky URL: http://www.z6688.com/
the above information and the article body is an integral part, if you want to reprint this article, please keep the above information, thank you!

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.