0%
文件分片和计算哈希
文件分片
客户端选择一个文件之后,要对文件进行分片,方便后续上传。
文件切片方法
javascript
/**
* 文件切片
* @param {*} file 文件对象
* @param {*} chunkSize 切片大小 字节
* @returns Blob[]
*/
function splice(file, chunkSize) {
const result = []
for (let i = 0; i < file.size; i += chunkSize) {
result.push(file.slice(i, i + chunkSize))
}
return result
}
计算文件哈希值
由于要支持任意大小的文件,所以要使用切片进行增量计算。不能一下子把整个文件全读进内存里,要是用户一下选了一个 1T 的视频内存直接就炸了。
javascript
function hash(chunks) {
return new Promise((resolve, reject) => {
const spark = new SparkMD5()
function _read(i) {
if (i >= chunks.length) {
resolve(spark.end())
return
}
const blob = chunks[i]
const reader = new FileReader()
reader.onload = e => {
const bytes = e.target.result
spark.append(bytes)
_read(i + 1)
}
reader.readAsArrayBuffer(blob)
}
_read(0)
})
}
计算哈希值的时候用了 SparkMD5
的库。后面的代码有提到。
demo
一个文件分片和计算哈希值的 demo 如下。
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件分片上传</title>
<script src="./spark-md5.min.js"></script>
<script src="lib.js"></script>
</head>
<body>
<input id="file" type="file">
<script src="./index.js"></script>
</body>
</html>
javascript
window.onload = function() {
const fileDom = document.getElementById('file')
fileDom.addEventListener('change', async e => {
const file = fileDom.files[0]
const chunks = splice(file, 10 * 1024 * 1024)
console.log(`这个文件有这么大:${file.size}`, '分了这么多片: ', chunks)
const md5 = await hash(chunks)
console.log('文件哈希是', md5)
})
}
javascript
/**
* 文件切片
* @param {*} file 文件对象
* @param {*} chunkSize 切片大小 b
* @returns Blob[]
*/
function splice(file, chunkSize) {
const result = []
for (let i = 0; i < file.size; i += chunkSize) {
result.push(file.slice(i, i + chunkSize))
}
return result
}
function hash(chunks) {
return new Promise((resolve, reject) => {
const spark = new SparkMD5()
function _read(i) {
if (i >= chunks.length) {
resolve(spark.end())
return
}
const blob = chunks[i]
const reader = new FileReader()
reader.onload = e => {
const bytes = e.target.result
spark.append(bytes)
_read(i + 1)
}
reader.readAsArrayBuffer(blob)
}
_read(0)
})
}
javascript
// 前往 https://github.com/satazor/js-spark-md5/releases/tag/v3.0.2 下载