1. 程式人生 > >檔案上傳之切片

檔案上傳之切片

今天主要講講檔案切片,主要在上傳大檔案的時候需要用到,你想想,上傳一個幾百兆的大視訊,但網路頻寬又特別感人,一個不小心就報錯造成上傳失敗,那是什麼感受...

       進入正題,選擇檔案後,點選“確定”,首先計算出檔案總大小,然後需要做什麼呢,你需要告訴伺服器這個大檔案被切成了多少片,還得在每次上傳的時候告訴它當前是第幾片。最好加一個Date.now(),不然大家同時上傳一個1.jpg,一到伺服器就重名了,加了Date.now(),1_(時間戳).jpg就不會重名了。

       每次上傳的Blob物件使用file.slice(start, end)完成:


注意紅框標註的地方,每次上傳都需要執行formData['delete'](fileName)

,至於原因已經在裡面加入了,自己看哈。

下面是上傳進度和上傳速度的程式碼:

var xhr = ZUtil.getXHR(),
formData = new FormData(),
// 上次的時間戳
prev = new Date().getTime(),
// 以上傳
load = 0,
// 檔案大小
size = file.size,
translateSize = ZUtil.translateByte(size),
prevProgress = 0,
$bar = $row.find('.z-progress-bar'),
$progress = $row.find('.z-upload-progress'),
$speed = $row.find('.z-upload-speed'),
$progressLinear = $row.find('.z-upload-progress-linear');formData.append('uniqueFlag', Date.now());
formData.append('fileName', file.name);xhr.addEventListener('error', uploadError, false);
xhr.upload.addEventListener('progress', function(e) {
// e.loaded是本次請求已經上傳的檔案大小
var loaded,
// 當前時間戳
now = new Date().getTime(),
distance = now - prev;
if (splitUpload) {
/**
* 如果是分片上傳,e.loaded是每次的file.slice(start, end),理論上就是每份檔案切片大小
* 而不會像整體檔案上傳一樣,e.loaded是從0慢慢增長到file.size
* 需要加上load才是已經上傳的檔案大小
*/
loaded = e.loaded + load;
} else {
loaded = e.loaded;
}var progress = Math.min(Math.round(loaded / size * 100), 100);
/**
* 每次更新的時間間隔 >= speedUpdateInterval
* 或者上傳完畢(如果是分片上傳,那麼e.loaded >= splitSize也意味著當前分片檔案上傳完成)
*/
if(distance >= speedUpdateInterval || (progress == 100 || (splitUpload && e.loaded >= splitSize))) {
var speed = ZUtil.translateByte((loaded - load) / distance * 1000);
$speed.html('速度:' + speed + '/s');
prev = now;
load = loaded;
}
if(progress != prevProgress) {
prevProgress = progress;
$progress.html('進度:' + progress + '% of ' + translateSize);
$progressLinear.css({
width : progress + '%'
});
}

下面是檔案上傳效果:

第一個切片:


最後一個切片:


大家也看到了,檔案只有216KB,我設定的切片大小隻有0.01MB,所以才會上傳22次。


        onreadystatechange程式碼


       可以看到,每次需要後端返回success,並且當前切片index < 總切片數totalIndex才會繼續上傳,如果全部上傳完畢,會呼叫afterUpload回撥方法

後端java程式碼


       通過對比index和totalIndex,如果相同,就合併檔案

       上一篇已經提過如果不適用切片,僅僅一個進度條,這都是騙人的。使用切片後,分片上傳檔案,等到上一片檔案上傳成功後才會繼續上傳下一片,因為公司沒有要求使用資料庫記錄切片資訊,所以每次上傳切片後沒有將切片檔案資訊儲存到資料庫,要是哪個切片上傳失敗了,只能重新上傳...這樣做雖然花費的時間長了一點(當然了,這麼多次請求,HTTP握手肯定很費時間的),不過這樣也是值得的,幾百兆的大檔案重複上傳更費時間呢,反正還是需要開發者自己權衡,個人建議,幾兆的小檔案就別用切片了,麻煩。

相關推薦

檔案切片

今天主要講講檔案切片,主要在上傳大檔案的時候需要用到,你想想,上傳一個幾百兆的大視訊,但網路頻寬又特別感人,一個不小心就報錯造成上傳失敗,那是什麼感受...        進入正題,選擇檔案後,點選“確定”,首先計算出檔案總大小,然後需要做什麼呢,你需要告訴伺服器這個大檔案

Servlet檔案FileItem類的常用方法

1.  boolean isFormField() isFormField方法用於判斷FileItem類物件封裝的資料是一個普通文字表單欄位,還是一個檔案表單欄位,如果是普通表單欄位則返回true,否則返回false。因此,可以使用該方法判斷是否為普通表單域,還是檔案上傳表

commons-fileupload 檔案細節

目錄 1、把上傳的檔案放到WEB-INF目錄下 2、檔名稱(完整路徑、檔名稱) 3、中文亂碼問題 4、上傳檔案同名問題(檔案重新命名) 5、一個目錄不能存放過多的檔案(存放目錄打散) 6、上傳的單個檔案的大小限制和整個表單大小限

JS 檔案 FileReader

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>SA</title> <link rel="style

javaweb基礎第二十四課:檔案準備工作

大綱: 檔案表單域 上傳檔案要注意的事項     這節課我們開始學檔案的上傳和下載,我先準備好檔案。OK。   然後我們學習下檔案上傳的前端注意事項。   檔案表單域 我們要上傳檔案首先要寫個檔案表單域,寫

Retrofit2+RxJava學習小計(一):單檔案、多檔案填平的坑

從Eclipse轉戰AndroidStudio已經有兩個月了。先誇誇Google親兒子的強大吧,各種方便就不一一道來了。主要是現在的Android陣營已經不想前兩年了。各種開源框架開源庫。也正是如此,AndroidStudio匯入開源的專案非常方便。自從Goog

Ajax 檔案PHP心得

       最近發現網上轉載不註明出處的文章很多,為了創造一個良好的開源環境.請您轉載後註明出處.謝謝合作!這樣會鼓勵我們的開源慾望. jquery 這個JS元件不知道大家用過沒有?在有一定的Ajax基礎之後,利用它來開發Ajax是一件非常有趣的事情,一直以來就被Js的傳統

PHP大檔案切片

由於專案需要,經常要上傳幾百兆或者幾個G的檔案。考慮到檔案過大,直接上傳的話會超出PHP設定的表單提交限制大小,同時會佔用較多的系統資源。於是考慮將檔案進行切片,然後將切片後的檔案統一上傳至檔案目錄,待全部上傳成功之後再將其合併成一個檔案,同時後臺md5驗證是否上傳成功。

falsk檔案

  在使用flask定義路由完成檔案上傳時,定義upload檢視函式 from flask import Flask, render_template from werkzeug.utils import secure_filename import os app = Flask

laravel框架檔案

引用use檔案 控制器引用模型檔案方便呼叫 use App\Info\Info; 模型引用DB檔案 use Illuminate\Support\Facades\DB;   model模型中的程式碼 public function index(){ //

Sentry命令列工具PDB檔案

Sentry尚不直接支援Microsoft PDB檔案。在我們提供官方支援之前,您可以將它們轉換為Breakpad符號並上傳它們: 獲取.pdb檔案並將其放在Windows計算機上 下載我們的Windows Breakpad Tools並解壓縮dump_syms.exe 執行d

Spring Boot 整合檔案與下載

1.匯入依賴 <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId>

Struts2檔案與下載

1、檔案上傳三種方式: 將檔案以二進位制的形式儲存到資料庫中 activiti工作流框架  將檔案儲存到專門檔案伺服器(存放檔案用的Linux系統)中  直接將檔案儲存到伺服器(tomcat所在伺服器)中 2、檔案上傳的一個例項: action裡

【Android架構】基於MVP模式的Retrofit2+RXjava封裝檔案(三)

最近手頭事比較多,抽個空把之前系列也補充一下。 先回顧下之前的 【Android架構】基於MVP模式的Retrofit2+RXjava封裝(一) 【Android架構】基於MVP模式的Retrofit2+RXjava封裝之檔案下載(二) 今天要說的是檔案上傳 1.單圖上

SpringCloud Fegin —— 傳送GET、POST請求以及檔案

                       深信自己通過學習理解寫出來的才是自己的 --

Bootstrapfileinput檔案控制元件

 前言~ 前段時間做專案用到了bootstrap裡中的檔案上傳控制元件,對此特定寫這篇文章,講述一下bootstrap的檔案上傳空間的使用方法。 我們進入正題吧!        首先bootstrap是基於jquery的,因此要匯入

SpringCloud從入門到進階(七)——踩坑實戰Zuul服務呼叫失敗與檔案問題

內容   上一節搭建了具有服務熔斷、負載均衡的微服務架構1.0 ,但是在通過路由呼叫微服務時出現了一些直接呼叫微服務沒有的問題,這也是筆者專案中遇到的真實問題。本文查閱了官方文件等資料,介紹該問題的解決方法。 版本   IDE:IDEA 2017.2.2 x64   JDK:1.8.0_171   

web安全檔案漏洞攻擊與防範方法

一、 檔案上傳漏洞與WebShell的關係 檔案上傳漏洞是指網路攻擊者上傳了一個可執行的檔案到伺服器並執行。這裡上傳的檔案可以是木馬,病毒,惡意指令碼或者WebShell等。這種攻擊方式是最為直接和有效的,部分檔案上傳漏洞的利用技術門檻非常的低,對於攻擊者來說很容易實施。 檔案上傳漏洞本身就是一

react-native檔案下載

目錄 檔案上傳 1.檔案選擇 2.檔案上傳 1.FormData物件包裝 2.上傳示例 檔案下載 最近react-native專案上需要做檔案上傳下載的功能,由於才接觸react-native不久,好多東西不熟悉,前

Ajax(form表單檔案、請求頭contentType、Ajax傳遞json資料)

form表單檔案上傳 上菜 file_put.html <form action="" method="post" enctype="multipart/form-data"> {# 這裡必須要請求頭格式才能把上傳檔案的物件傳過去 enctype="multipart/form-