在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/HTML/ 斷點(diǎn)續(xù)傳問(wèn)題

斷點(diǎn)續(xù)傳問(wèn)題

我的需求簡(jiǎn)單描述為:

 對(duì)于大文件按照一定的chunkSize大小切分為許多小文件上傳存儲(chǔ)在mongodb中,
 下載時(shí)通過(guò)node.js發(fā)起n(n為切分的小文件的個(gè)數(shù))個(gè)下載請(qǐng)求,每個(gè)請(qǐng)求請(qǐng)求
 一部分?jǐn)?shù)據(jù),最后通過(guò)writeStream寫入到同一個(gè)文件中。系統(tǒng)的整體流程描述如上。

現(xiàn)在要做的工作是:

 上述的功能已經(jīng)完成,現(xiàn)在要做的是下載過(guò)程中的斷點(diǎn)續(xù)傳問(wèn)題,即就是下載時(shí)如何
 本地文件中已有該部分?jǐn)?shù)據(jù)則跳過(guò)該部分的下載。

遇到的問(wèn)題:

現(xiàn)在的問(wèn)題是,如何用簡(jiǎn)單的方法判斷文件中的某一個(gè)部分是否已經(jīng)存在(我想簡(jiǎn)單的
通過(guò)判斷某一塊的第一個(gè)<0>和最后一個(gè)<chunkSize-1>處的文件描述符是否有內(nèi)容來(lái)
判斷此塊是否已經(jīng)下載完成),請(qǐng)問(wèn)各位碼友Node.js中的文件描述符fd是否已有像C語(yǔ)言
中的seek方法(文件描述符移動(dòng)到指定的位置),移動(dòng)到指定位置后怎么判斷此處是否有內(nèi)容。
謝謝各位碼友。
下載部分的代碼如下(其中downloadpromise是我自己封裝的用來(lái)下載每一塊數(shù)據(jù)的Promise):
 function download(filedata,username,chunkSize) {
 var chunks_n = Math.ceil(filedata.length/filedata.chunkSize);
 var file_id = filedata._id;
 var DLpromiseall = [];

 //創(chuàng)建對(duì)應(yīng)的文件,為以后createWrite而使用
 fs.open(filedata.filename, "a", (err, fs) => {
     if (err) {
         console.log(err);
     }
 })
 
 for(let curindex = 0;curindex < chunks_n;curindex++) {
     DLpromiseall.push(downloadpromise(username,file_id,curindex,filedata.filename,chunkSize));
 }
 var mytimer = setInterval(() => {
     if(DLpromiseall.length == chunks_n) {
         clearInterval(mytimer);
         Promise.all(DLpromiseall).then(vales=>{
             console.log(vales);
             console.log("all download")
         }).catch(err =>{
             console.log(err);
             console.log("下載失敗");
         })
     }
 },500)
}

downloadPromise函數(shù)如下:

 * 文件下載邏輯
 **/
function  downloadpromise(username,file_id,n,filename,chunkSize) {
    return new Promise(function (resolve,reject) {
        let mydata = {
            username: username,
            file_id: file_id,
            n: n
        };
        let contents = queryString.stringify(mydata);
        let options = {
            host: "localhost",
            path: "/nodedownload/",
            port: 8000,
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Content-Length': contents.length
            }
        };
        let req = http.request(options, function (res) {
            let bufs = [];
            res.on("data", function (chunk) {
                bufs.push(chunk)
            });
            res.on("end", function (d) {
                console.log("end")
                var resubuf = Buffer.concat(bufs)
                var resu = new Buffer(JSON.parse(resubuf));
                try {
                    let WSoptions = {
                        start: n*chunkSize,
                        flags: "r+"
                    }
                    let WStream = fs.createWriteStream(filename,WSoptions)
                    WStream.write(resu,function () {
                        console.log("This is : "+n);
                    });
                    WStream.end();
                    resolve(filename);
                }catch (err) {
                    console.log(err);
                    reject(err);
                }
            });
            res.on("error", function (e) {
                throw e;
            })
        });
        req.write(contents);
        req.end();
    })
}
回答
編輯回答
硬扛
上述的功能已經(jīng)完成,現(xiàn)在要做的是下載過(guò)程中的斷點(diǎn)續(xù)傳問(wèn)題,即就是下載時(shí)如何
本地文件中已有該部分?jǐn)?shù)據(jù)則跳過(guò)該部分的下載。

在原有的http協(xié)議,客戶端會(huì)通過(guò)Range請(qǐng)求服務(wù)器要返回的部分內(nèi)容(先判斷本地已經(jīng)下載了幾個(gè)字節(jié)),服務(wù)端通過(guò)Content-Range告知客戶端目前返回下來(lái)的部分內(nèi)容。而你這里多出來(lái)的一部只是分塊而已,都是一樣的。

通過(guò)option.start指定文件流開始的位置。

fs.createReadStream(filePath, {
     start: startRange,
     end : endRange //如果需要
});
2018年3月17日 04:30
編輯回答
刮刮樂(lè)

暫時(shí)想到了一個(gè)不是很成熟的想法,通過(guò)判斷每一塊里面是否有寫入的內(nèi)容,以及寫入的內(nèi)容是否達(dá)到規(guī)定寫入的標(biāo)準(zhǔn)。代碼如下

function readPromise(filepath,i,options) {
    return new Promise(function (resolve,reject) {
        let flag = false;
        let readStream = fs.createReadStream(filepath,options);
        readStream.on("data",(chunk)=>{
            let chunString = chunk.toString().trim();
            let nsize = options.end - options.start + 1;
            if(!chunString||chunString.length < nsize) {
                flag = true;
            }
        })
        readStream.on("close",(ele) => {
            resolve(flag);
        })
        readStream.on("error",(e) => {
            reject(e);
        })
    })
}
2017年12月5日 19:36