<!-- spark-md5 hash值计算插件 -->
<script src="spark-md5.min.js"></script>
<input type="file">
<script>
/*
* 补充说明:
* 大文件分片上传,计算hash值时,文件很大时运算时间非常长,因为它是cpu特别密集的任务,
* 所以非常消耗cpu,所以最好单开一个线程做文件处理
* 扩展:单开线程需要了解web work知识
*/
const inp = document.querySelector('input');
//这里须要用到File的slice( )方法,如下是兼容写法
const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
inp.onchange = async (e) => {
const file = inp.files[0]
if (!file) { // 判断是否获取到文件,取到直接return回去
return;
}
/*
const piece = file.slice(0, 100);// 0-99个字节的数据
console.log(piece) // 输出:Blob {size: 100, type: ''}
*/
const chunks = createChunks(file, 10 * 1024 * 1024) // 分片10M
/*
* 拿到分片数据可以利用接口的方式上传
*/
console.log(chunks)// 获取到分片后的文件片段数据
const result = await hash(chunks)
/*
* 拿到文件的唯一hash值,就可以配合后端,做文件暂停、继续、网络异常导致的上传失败,下次继续上传
*/
console.log(result) // 拿到文件的唯一hash值
}
function hash(chunks) { // 计算文件的hash值
return new Promise((resolve, reject) => {
const spark = new SparkMD5() //建立SparkMD5的实例
function _read(i) {
if (i >= chunks.length) { // i 大于等于分片数组的长度返回文件计算出的唯一Hash值
resolve(spark.end()) // 完成计算,返回结果
return;//
}
const blob = chunks[i] // 获取文件的分片数组中的一个文件
const reader = new FileReader(); //建立FileReader的实例
reader.onload = e => { // FileReader的load事件,当文件读取完毕时触发
const bytes = e.target.result // 读取到字节的数组
spark.append(bytes) // spark-md5 // 开始计算Hash值
_read(i + 1)// 递归
}
reader.readAsArrayBuffer(blob);//经过fileReader读取文件二进制码
}
_read(0)// 初始计算
})
}
/*
* function 文件切片返回result
* file:文件内容
* chunksSize:文件切片的大小(字节)
*/
function createChunks(file, chunkSize) {
const result = []
for (let i = 0; i < file.size; i += chunkSize) {
result.push(blobSlice.call(file.slice(i, i + chunkSize)))
}
return result
}
</script>
前端大文件分片上传原理
于 2023-03-07 19:21:10 首次发布
文章介绍了在处理大文件上传时,如何利用Spark-MD5库计算文件的hash值以实现断点续传。通过文件分片、WebWorker来减少CPU消耗,提高性能,并提供了一个创建文件分片和计算hash值的示例代码。
摘要由CSDN通过智能技术生成