升完级服务器上生成大文件,基于node服务器的大文件(G级)上传

原理如:3G的大文件分1500个2M二进度文件,通post方法发送给node服务,服务器全部接收到文件后,进组装生成你上文件。

需要了解以下node库,:

客户端代码:

//异步库

$(function(){

$('#userbtn').on('click',function(){

var file= $("#uppic")[0].files[0],//上传文件主体

name = file.name,        //文件名

size = file.size,        //总大小

succeed = 0;  //当前上传数

var shardSize = 2 *1024*1024,    //以2MB为一个分片

shardCount = Math.ceil(size / shardSize);  //总片数

/*生成上传分片文件顺充,通过async.eachLimit()进行同步上传

attr里面是[0,1,2,3...,最后一位]

*/

var attr=[];

for(var i=0;i

attr.push(i);

}

async.eachLimit(attr,1,function(item,callback){

var i=item;

var start = i * shardSize,//当前分片开始下标

end = Math.min(size, start + shardSize);//结束下标

//构造一个表单,FormData是HTML5新增的

var form = new FormData();

form.append("data", file.slice(start,end));  //slice方法用于切出文件的一部分

form.append("name", name);//文件名字

form.append("total", shardCount);  //总片数

form.append("index", i + 1);   //当前片数

//Ajax提交

$.ajax({

url: "/dafile",

type: "POST",

data: form,

timeout:120*1000,

async: false,        //同步

processData: false,  //很重要,告诉jquery不要对form进行处理

contentType: false,  //很重要,指定为false才能形成正确的Content-Type

success: function(data){

++succeed;

var data=eval('('+data+')');

/*返回code为0是成功上传,1是请继续上传*/

if(data.code==0){

console.log(data.msg);

}else if(data.code==1){

console.log(data.msg);

}

//生成当前进度百分比

var jd=Math.round(succeed/shardCount*100)+'%';

$('.jdb').html(jd);

/*如果是线上,去掉定时,直接callback(),

这样写是为方便,本地测试看到进度条变化

因为本地做上传测试是秒传,没有时间等待*/

setTimeout(callback,50);

}

});

},function(err){

console.log('上传成功');

});

});

});

服务器代码:

function user(req,res,config){

var path=require('path');

var fs=require('fs');

var multiparty = require('multiparty');//文件上传模块

var async = require('async');//异步模块

var form = new multiparty.Form();//新建表单

//设置编辑

form.encoding = 'utf-8';

//设置文件存储路径

form.uploadDir = "Uploads/img/";

//设置单文件大小限制

// form.maxFilesSize = 200 * 1024 * 1024;

/*form.parse表单解析函数,fields是生成数组用获传过参数,files是bolb文件名称和路径*/

form.parse(req, function (err,fields,files) {

files=files['data'][0];//获取bolb文件

var index=fields['index'][0];//当前片数

var total=fields['total'][0];//总片数

var name=fields['name'][0];//文件名称

var url='Uploads/img/'+name+index;//临时bolb文件新名字

fs.renameSync(files.path,url);//修改临时文件名字

var pathname='Uploads/img/'+name;//上传文件存放位置和名称

if(index==total){//当最后一个分片上传成功,进行合并

/*

检查文件是存在,如果存在,重新设置名称

*/

fs.access(pathname,fs.F_OK,(err) => {

if(!err){

var myDate=Date.now();

pathname='Uploads/img/'+myDate+name;

console.log(pathname);

}

});

//这里定时,是做异步串行,等上执行完后,再执行下面

setTimeout(function(){

/*进行合并文件,先创建可写流,再把所有BOLB文件读出来,

流入可写流,生成文件

fs.createWriteStream创建可写流

aname是存放所有生成bolb文件路径数组:

['Uploads/img/3G.rar1','Uploads/img/3G.rar2',...]

*/

var writeStream=fs.createWriteStream(pathname);

var aname=[];

for(var i=1;i<=total;i++){

var url='Uploads/img/'+name+i;

aname.push(url);

}

//async.eachLimit进行同步处理

async.eachLimit(aname,1,function(item,callback){

//item 当前路径, callback为回调函数

fs.readFile(item,function(err,data){

if(err)throw err;

//把数据写入流里

writeStream.write(data);

//删除生成临时bolb文件

fs.unlink(item,function(){console.log('删除成功');})

callback();

});

},function(err){

if (err) throw err;

//后面文件写完,关闭可写流文件,文件已经成生完成

writeStream.end();

//返回给客服端,上传成功

var data=JSON.stringify({'code':0,'msg':'上传成功'});

res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});

res.end(data);//返回数据

});

},50);

}else{//还没有上传文件,请继续上传

var data=JSON.stringify({'code':1,'msg':'继续上传'});

res.writeHead(200, {'Content-Type': 'text/html;charset=utf-8'});

res.end(data);//返回数据

}

});

return user;

};

exports.init = user;

这是初步设计方案,后期加异步上传和断点续传功能。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值