Asp no-component upload progress bar Solution

Source: Internet
Author: User

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>

In the background asp program, it is very easy to obtain the ASCII data submitted by the form in the past. 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. In the code, we convert binary data read by BinaryRead into text and output it, 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>" '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, 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. 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
%>

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.

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.