实现代码:
function splitBuffer(buffer,sep) { let arr = []; let pos = 0;//当前位置 let sepPosIndex = -1;//分隔符的位置 let sepPoslen = Buffer.from(sep).length;//分隔符的长度,以便确定下一个开始的位置 do{ sepPosIndex=buffer.indexOf(sep,pos) if(sepPosIndex==-1){ //当sepPosIndex是-1的时候,代表已经到末尾了,那么直接直接一口读完最后的buffer arr.push(buffer.slice(pos)); }else{ arr.push(buffer.slice(pos,sepPosIndex)); } pos = sepPosIndex+sepPoslen }while(-1!==sepPosIndex) return arr } 前端部分: H5中fileAPi的slice方法slice之前是用于数组的一个方法,现在文件也可以用slice来分割拉,不过需要注意的是这个方法是一个新的api,也就是很多old的浏览器无法使用。
用法很简单:
//初始位置,长度 //这里的File对象是一个Blob,一个类似于二进制的流,所以这里是以字节为单位的。 File.slice(startByte, length); JS的原生AJAX实现方式XMLHttpRequest新建一个XMLHttpRequest
xhr = new XMLHttpRequest();打开一个post为请求的链接
xhr.open("post", "/submit", true);配置onreadystatechange,捕获请求链接的状态。
xhr.onreadystatechange = function(){ //xhr.readyState //处理完成的逻辑 }; readyState 意义0 初始化
1 加载中
2 加载完成
3 部分可用
4 加载完成
准备工作都做好了,最后send一下,请求链接。
xhr.send(表单数据);下面一节会写如何生成send中的表单数据
封装表单数据FormDataFormData的使用很友好,就是按照健值一个个配对就可以了。
var formData = new FormData(); formData.append("test", "I am FormData"); formData.append("file", 你选择的文件);虽然简单,但是却可以模拟post的数据格式send给服务器。
详细用法,点我
断点续传 主要逻辑写了这么多有关之后开发断点续传的相关知识点,我们可以动手开始写了。断点续传的逻辑并不复杂大概就是这样的:
客户端client 服务器端server我想上传一个文件 ok,no problem,不过你只能用post传给我
我的文件很大直接form提交可以吗 有多大,如果很大的话,一旦我们的连接断开,我们就前功尽弃了啊!慎重啊!
well,well,我把我的文件slice成一小块一小块慢慢给你行了吧 来吧baby~,我不介意你多来几次
第一部分send 接受中...
等待中... 接受完毕,处理接受的Blob,处理完毕已写入,你可以传第二部分了~
第二部分send 接受中...
等待中... 接受完毕,处理接受的Blob,处理完毕已写入,你可以传第三部分了~
... ...
... 终于结束了,我去处理下你的文件
... ok~传送成功
断点续传client端的处理方式
从上述逻辑来看,这个前端的流程可以分为:
确定文件大小,根剧相同的长度切片
根据切片的数量,进行回调上传
切分文件断点续传是客户端主动发送,服务器端被动接受的一个过程,所以这里是在客户端进行一个文件的切分,把文件根据range的大小进行切分,range的大小可以自定义。这里我为了防止每次上传切片都要计算位置,所以提前把所有的位置都放入了currentSlice的数组之中。然后按顺序取位置。注意:这边切分全部是以字节为单位的计算。
createSlices(){ let s=0,e=-1,range=1024; for(let i = 0;i<Math.ceil(this.file.size/range);i++){ s=i*range,e=e+range e=e>this.file.size-1?this.file.size-1:e; this.currentSlice.push([s,e]) } }