I hope that one day we can learn from innovation

 

I haven’t been working on this file upload progress display recently, CSS effects are left behind. Just because I did file upload before, I didn’t really think about the upload schedule. A few days ago, I saw a blog and felt that the uploading schedule would be encountered sooner or later. Here is a brief introduction to the general implementation methods and ideas, I hope to step on the pit partner, with the help of this article can pit more smoothly.

Necessary tools:

html css java

I’m going to use the Springboot framework as a base project demo just to be lazy.

Basic framework construction:

Use Bootstrap to integrate front-end styles. I’m not good at writing styles. Write the basic upload file editing position, here is focused on the realization of file segmentation business.

The methods of file segmentation can be simply divided into two kinds: ① fixed block segmentation ② fixed length segmentation

Block split: Regardless of the size of the file, the number of blocks that define the file split is defined. For example, I used this method in this project, defining the size of the uploaded file to be divided into 10 pieces. From a professional point of view, this segmentation method is too rough and there are many problems, but because here in order to show how to do file segmentation, so the optimization of the segmentation algorithm can be dynamically changed according to the business problem.

Fixed length segmentation: relative to fixed block segmentation, this way will be slightly better. The number of files is segmented according to the size of the file to be uploaded. The number of requests to the upload interface also varies according to the size of the file.

Of course, it seems that none of these methods are the best for splitting, but file splitting is put on the client side to reduce the accidental case that a single large file upload can cause a rat to ruin the pot.

File splitting:

Using fixed block split file, simple code implementation:

 /* Cut file method */ function sliceFiles(file, num) { var fileList = []; var singleSize = Math.ceil(file.size / num); var location = 0; while (location < file.size) { fileList.push(file.slice(location, location + singleSize)); location += singleSize; } return fileList; }
Copy the code

/ function sliceFiles(file, num) {var fileList = []; var singleSize = Math.ceil(file.size / num); var location = 0; while (location < file.size) { fileList.push(file.slice(location, location + singleSize)); location += singleSize; } return fileList; }

To upload the obtained file, the backend needs to provide an excuse for uploading the file. In this case, FormData is used for uploading the file. The interface for receiving file uploads is positioned as follows:

The purpose of file fragment upload is to achieve faster file upload. Therefore, it is meaningless to call the file upload interface repeatedly after each file split operation compared with single upload. Therefore, we set the mode of uploading the file as asynchronous method, and wait for the end of the file shard to execute the call method at the same time.

 function uploadFileSingle(index, file) { return new Promise(function (resolve, reject) { console.log("content--------", index); var formData = new FormData(); formData.append("file", file); formData.append("index", index); $.ajax({ url: '/file/uploadSingle? _t=' + new Date().getMilliseconds(), type: "POST".processData: false.contentType: false.mimeType: "multipart/form-data".data: formData, success: function (data) { resolve.apply(data); }, error: function (data) { reject.apply(data); }}); })}Copy the code

Specific call:

The mergeFile method mentioned in the code is to merge the files uploaded by sharding, because sharding is just the purpose, and merging is to keep the uploaded files in their original state.

Merge files:

Talking about file block upload, we have to say how the file merges the final file idea. A file still needs to have an execution identifier to facilitate final collection. Partitioned files need to be identified sequentially, such as 0,1,2 or other information to identify the file block after the file is partitioned. I’m just here to demonstrate the effect of the project, I just define the file name for them after splitting: 0 1 2 3 4 5 6 7 8 9.

So I finally got the files in numerical order when merging the files, and then merged the files.

Contrast effect:

There are actually a lot of benefits to doing this sharding, and I’ve done a simple comparison of execution times. Note: small files do not seem to prevail here, so the size of the files uploaded here is: 2.42GB

69.025

62.434

If you are interested, you can try it out. In addition to the limitations of my local broadband and other performance conditions, there will be a speed increase when files are slightly larger.

File merging

After the file is uploaded, you need to actively request the data to be merged, so you can initiate a request to merge the data files in the Promise’s then() method.

Back-end Java code implementation:


Next, we can do something interesting on this basis, optimize the interaction of upload waiting and add the display of upload progress.

You need to use XHR, specifically using ajax methods to get uploaded progress data:

 xhr: function () { var xhr = new XMLHttpRequest(); xhr.upload.addEventListener('progress'.function (e) { var progressRate = (e.loaded / e.total) * 100 + The '%'; $(` #${index} div`).attr("style".`width: ${progressRate}`); }); return xhr; }
Copy the code

With the progress display, the feeling of interaction weakness caused by ordinary loading waiting will be greatly optimized. Let’s take a look at the final effect:


Wechat public account: Technology sharing of code Farmer [Sorry for the slow update speed]

Source code please private letter file sharding

Zhihu account: Xi Xi Spring Breeze