Skip to content

文件分片和计算哈希

文件分片

客户端选择一个文件之后,要对文件进行分片,方便后续上传。

文件切片方法

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 下载

© thebestxt.cc
辽ICP备16009524号-8
本站所有文章版权所有,转载请注明出处