Heim > Java > javaLernprogramm > Hauptteil

Wie implementiert man mit Java die Breakpoint-Resume-Funktion von Dateien?

王林
Freigeben: 2023-04-27 15:22:07
nach vorne
1837 Leute haben es durchsucht

Was ist ein fortsetzbarer Upload?

Benutzer laden große Dateien hoch, was bei schlechter Netzwerkverbindung mehrere Stunden dauern kann. Wenn die Verbindung unterbrochen wird, müssen Server, die keine fortsetzbaren Uploads haben, die Übertragung erneut durchführen Sie können sie von Anfang an übertragen, und das Fortsetzen des Hochladens an einem Haltepunkt ermöglicht es Benutzern, die Übertragung an der Stelle fortzusetzen, an der der Upload unterbrochen wurde, was die Sorgen der Benutzer erheblich verringert.

  • Lösen Sie das Problem des unzureichenden Serverspeichers zum Hochladen großer Dateien Das Problem wurde aufgrund anderer Faktoren abgebrochen und der Upload kann nach dem Aktualisieren des Browsers weiterhin fortgesetzt werden. Der Upload kann nach dem Neustart des Browsers weiterhin fortgesetzt werden (Browser schließen und dann öffnen) und der Upload kann nach dem Neustart des Computers weiterhin fortgesetzt werden

  • Wenn der Inhalt der Datei aufgrund von Netzwerkschwankungen während des Upload-Vorgangs verloren geht, muss er automatisch erkannt und erneut hochgeladen werden

    #🎜🎜 #
  • Lösung

    #
  • Frontend

Die Dateien, die benötigt werden Um die Dateiseriennummer anzugeben, müssen Sie den Upload-Fortschritt überwachen und den Fortschrittsbalken steuern. 🎜🎜#Sie müssen die Zusammenführung senden, nachdem der Upload abgeschlossen ist. Anfrage

  • Blob-Objekt, Vorgangsdatei

  • #🎜 🎜#Backend
  • #🎜 🎜#
  • Schnittstelle zum Hochladen von Shards
  • Schnittstelle zum Zusammenführen von Shards# 🎜🎜 #
  • Punkte sammeln Die Schnittstelle des Stücks

Andere Werkzeugmethoden werden zur Unterstützung verwendet

#🎜🎜 #Worauf das Front-End achten muss, ist: Dateischneiden und Fortschrittsbalken

    Was Sie im Backend beachten müssen, ist: wo die Shards sind werden gespeichert und wie man die Shards zusammenführt #
  • Der Fortschrittsbalken ändert sich, wenn wir mit dem Hochladen beginnen, und der Fortschrittsbalken stoppt, wenn wir auf klicken, um den Upload zu stoppen#🎜 🎜#

  • Unser Backend wird es tun Verwenden Sie den Dateinamen + die Dateigröße in MD5, um die entsprechenden Verzeichnisergebnisse wie folgt zu generieren:

  • # 🎜🎜#
  • Wenn die hochgeladene Datei im Frontend 100 % erreicht, Es wird eine Dateizusammenführungsanforderung gesendet, und dann werden alle Shards in unserem Back-End zu einer Datei zusammengeführt dass alle Shards weg sind und somit eine Datei zusammengeführt wird der Stream geht verloren (vergleichen Sie die Größe)

  • Während des Datei-Upload-Vorgangs hat der Server Fragmente verloren (vergleichen Sie die Kontinuität der Fragmente)

    # ?? 🎜🎜#

Referenzcode

Frontend

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <h2>html5大文件断点切割上传</h2>
    <div id="progressBar"></div>

    <input id="file" name="mov" type="file" />
    <input id="btn" type="button" value="点我上传" />
    <input id="btn1" type="button" value="点我停止上传" />

    <script type="module">
        import FileSliceUpload  from &#39;../jsutils/FileSliceUpload.js&#39;
        let testingUrl="http://localhost:7003/fileslice/testing"
        let uploadUrl="http://localhost:7003/fileslice/uploads"
        let margeUrl="http://localhost:7003/fileslice/merge-file-slice"
        let progressUrl="http://localhost:7003/fileslice/progress"
         let fileSliceUpload=  new FileSliceUpload(testingUrl,uploadUrl,margeUrl,progressUrl,"#file")
         fileSliceUpload.addProgress("#progressBar")
          let btn=  document.querySelector("#btn")
          let btn1=  document.querySelector("#btn1")
        btn.addEventListener("click",function () {
            fileSliceUpload.startUploadFile()
        })
        btn1.addEventListener("click",function () {
            fileSliceUpload.stopUploadFile()
        })

    </script>


</body>

</html>
Nach dem Login kopieren
rrree

backend

# 🎜🎜#Weil der Code verwendet viele selbst -gekapselte Werkzeugklassen, der folgende Code stellt nur eine Referenz für das Prinzip dar

//大文件分片上传,比如10G的压缩包,或者视频等,这些文件太大了  (需要后端配合进行)
class FileSliceUpload{
     
    constructor(testingUrl, uploadUrl, margeUrl,progressUrl, fileSelect) {
            this.testingUrl = testingUrl; // 检测文件上传的url
            this.uploadUrl = uploadUrl;//文件上传接口
            this.margeUrl = margeUrl; // 合并文件接口
            this.progressUrl = progressUrl; //进度接口
            this.fileSelect = fileSelect;
            this.fileObj = null;
            this.totalize = null;
            this.blockSize = 1024 * 1024; //每次上传多少字节1mb(最佳)
            this.sta = 0; //起始位置
            this.end =  this.sta +  this.blockSize; //结束位置
            this.count = 0; //分片个数
            this.barId = "bar"; //进度条id
            this.progressId = "progress";//进度数值ID
            this.fileSliceName = ""; //分片文件名称
            this.fileName = "";
            this.uploadFileInterval = null;  //上传文件定时器

    }

    /**
     *  样式可以进行修改
     * @param {*} progressId   需要将进度条添加到那个元素下面
     */
    addProgress (progressSelect) {
        let bar = document.createElement("div")
        bar.setAttribute("id", this.barId);
        let num = document.createElement("div")
        num.setAttribute("id", this.progressId);
        num.innerText = "0%"
        bar.appendChild(num);
        document.querySelector(progressSelect).appendChild(bar)
     
    }
    //续传  在上传前先去服务器检测之前是否有上传过这个文件,如果还有返回上传的的分片,那么进行续传
    // 将当前服务器上传的最后一个分片会从新上传, 避免因为网络的原因导致分片损坏 
    sequelFile () {
        if (this.fileName) {
            var xhr = new XMLHttpRequest();
            //同步
            xhr.open(&#39;GET&#39;, this.testingUrl + "/" + this.fileName+ "/" + this.blockSize+ "/" + this.totalize, false);
            xhr.send();
            if (xhr.readyState === 4 && xhr.status === 200) {
                let ret = JSON.parse(xhr.response)
                if (ret.code == 20000) {
                   let data= ret.data
                    this.count = data.code;
                    this.fileSliceName = data.fileSliceName
                    //计算起始位置和结束位置
                    this.sta = this.blockSize * this.count
                    //计算结束位置
                    this.end = this.sta + this.blockSize
                } else {
                    this.sta = 0; //从头开始
                    this.end = this.sta + this.blockSize;
                    this.count = 0; //分片个数
                }
            }
        }
    }

    stopUploadFile () {
        clearInterval(this.uploadFileInterval)
    }

    // 文件上传(单文件)
    startUploadFile () { 
         // 进度条
         let bar = document.getElementById(this.barId)
         let progressEl = document.getElementById(this.progressId)
        this.fileObj = document.querySelector(this.fileSelect).files[0];
        this.totalize = this.fileObj.size;
        this.fileName = this.fileObj.name;
 
        //查询是否存在之前上传过此文件,然后继续
        this.sequelFile()
        let ref = this; //拿到当前对象的引用,因为是在异步中使用this就是他本身而不是class
        this.uploadFileInterval = setInterval(function () {
                if (ref.sta > ref.totalize) {
                    //上传完毕后结束定时器
                    clearInterval(ref.uploadFileInterval)
                    //发送合并请求
                    ref.margeUploadFile ()
                    console.log("stop" + ref.sta);
                    return;
                };
                //分片名称
                ref.fileSliceName = ref.fileName + "-slice-" + ref.count++
                //分割文件 ,
                var blob1 =  ref.fileObj.slice(ref.sta, ref.end);
                var fd = new FormData();
                fd.append(&#39;part&#39;, blob1);
                fd.append(&#39;fileSliceName&#39;, ref.fileSliceName);
                fd.append(&#39;fileSize&#39;, ref.totalize);
                var xhr = new XMLHttpRequest();
                xhr.open(&#39;POST&#39;,  ref.uploadUrl, true);
                xhr.send(fd); //异步发送文件,不管是否成功, 会定期检测

                xhr.onreadystatechange = function () {
                    if (xhr.readyState === 4 && xhr.status === 200) {
                        let ret = JSON.parse(xhr.response)
                        if (ret.code == 20000) {
                            //计算进度
                            let percent =  Math.ceil((ret.data*ref.blockSize/ ref.totalize) * 100)
                            if (percent > 100) {
                                percent=100
                                
                            }
                            bar.style.width = percent + &#39;%&#39;;
                            bar.style.backgroundColor = &#39;red&#39;;
                            progressEl.innerHTML = percent + &#39;%&#39;
                        }
                    }
            }


            //起始位置等于上次上传的结束位置
            ref.sta =  ref.end;
            //结束位置等于上次上传的结束位置+每次上传的字节
            ref.end = ref.sta + ref.blockSize;
        
        }, 5)

    }

    margeUploadFile () {
            console.log("检测上传的文件完整性..........");
            var xhr = new XMLHttpRequest();
            //文件分片的名称/分片大小/总大小
            xhr.open(&#39;GET&#39;, this.margeUrl+ "/" + this.fileSliceName + "/" + this.blockSize + "/" + this.totalize, true);
            xhr.send(); //发送请求
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    let ret = JSON.parse(xhr.response)
                    if (ret.code == 20000) {
                        console.log("文件上传完毕");
                    } else {
                        console.log("上传完毕但是文件上传过程中出现了异常", ret);
                    }
                }
            }
    
    }

}
export default FileSliceUpload;
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie implementiert man mit Java die Breakpoint-Resume-Funktion von Dateien?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!