js快速计算文件hash值
生活随笔
收集整理的這篇文章主要介紹了
js快速计算文件hash值
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1. 通過 requestIdleCallback or spark-md5利用瀏覽器空閑時間切片計算文件hash值:
requestIdleCallback簡介:
window.requestIdleCallback(): 方法將 在瀏覽器的空閑時段內調用的函數排隊。這使開發者能夠在主事件循環上執行后臺和低優先級工作,而不會影響延遲關鍵事件,如動畫和輸入響應。函數一般會按先進先調用的順序執行,然而,如果回調函數指定了執行超時時間timeout,則有可能為了在超時前執行函數而打亂執行順序。
file_hash.vue
<script> import sparkMD5 from 'spark-md5'export default { methods: {async uploadFile() {const hash = await fileHash()console.log("文件哈希是:", hash)...},async fileHash() {const chunks = []let cur = 0while (cur < this.file.size) { // this.file 為 e.target.files[0]chunks.push({ index: cur, file: this.file.slice(cur, cur + 1 * 1024 * 1024)}) // 1MB/片cur += size}return new Promise( resolve => {const spark = new sparkMD5.ArrayBuffer()let count = 0const appendToSpark = async file => {return new Promise( resolve => {const reader = new FileReader()reader.readAsArrayBuffer(file)reader.onload = e => {spark.append(e.target.result)resolve()}})}const workLoop = async deadline => {while (count < chunks.length && deadline.timeRemaining() > 1) {//瀏覽器存在空閑時間await appendToSpark(chunks[count].file)count++if (count < chunks.length) {this.hashProgress = Number( ((100 * count) / chunks.length).toFixed(2) )} else {this.hashProgress = 100resolve(spark.end())}}window.requestIdleCallback(workLoop) // 給 workLoop 函數一個瀏覽器狀態參數 deadline}window.requestIdleCallback(workLoop) // 給 workLoop 函數一個瀏覽器狀態參數 deadline})} } </script>2. 通過 Worker spark-md5 快速切片計算文件hash值:
Worker介紹:
Web Worker 的作用,就是為 JavaScript 創造多線程環境,允許主線程創建 Worker線程,將一些任務分配給后者運行。在主線程運行的同時,Worker線程在后臺運行,兩者互不干擾。等到 Worker 線程完成計算任務,再把結果返回給主線程。這樣的好處是,一些計算密集型或高延遲的任務,被 Worker 線程負擔了,主線程(通常負責 UI 交互)就會很流暢,不會被阻塞或拖慢。
Worker 線程一旦新建成功,就會始終運行,不會被主線程上的活動(比如用戶點擊按鈕、提交表單)打斷。這樣有利于隨時響應主線程的通信。但是,這也造成了 Worker 比較耗費資源,不應該過度使用,而且一旦使用完畢,就應該關閉。
目錄介紹:
├── static │ ├── hash.js //快速計算文件hash入口文件 (放在 static 文件夾是為了方便 Worker 訪問) │ └── spark-md5.min.js //需要用到 spark-md5 庫 ├── pages │ └── file_hash.vue //快速計算文件hash │ ... yarn add spark-md5 // 安裝該庫, 將其內部的 spark-md5.min.js 文件和 hash.js放在一起共 importScripts 訪問file_hash.vue
<script> export default { methods: {async uploadFile() {const hash = await fileHash()console.log("文件哈希是:", hash)...},async fileHash() {const chunks = []let cur = 0while (cur < this.file.size) { // this.file 為 e.target.files[0]chunks.push({ index: cur, file: this.file.slice(cur, cur + 1 * 1024 * 1024)}) // 1MB切片cur += size}return new Promise( resolve => {this.worker = new Worker('/hash.js')// 開啟一個外部進程this.worker.postMessage({ chunks }) // 給外部進程傳遞信息 this.worker.onmessage = e => { // 接收外部Worker回傳的信息const { progress, hash } = e.datathis.hashProgress = Number(progress.toFixed(2)) //計算hash值的進度條if (hash) {resolve(hash) // 得到計算出來的hash}}})} } </script>hash.js:
self.importScripts('spark-md5.min.js') // 引入 spark-md5self.onmessage = e => { // 接收主線程傳遞的參數const { chunks } = e.dataconst spark = new self.SparkMD5.ArrayBuffer()let progress = 0, count = 0const loadNext = index => {if (index == 0) {progress = 0count = 0}const reader = new FileReader()reader.readAsArrayBuffer(chunks[index].file)reader.onload = e => {count++spark.append(e.target.result) // 將讀取的內容添加入spark生成hashif (count == chunks.length) {self.postMessage({progress: 100,hash: spark.end()})} else {progress += 100 / chunks.lengthself.postMessage({ progress })loadNext(count)}}}loadNext(0) }拓展:通過抽樣加快hash的計算速度
方法:抽取文件內一部分字段放入 chunks 數組內,通過減小計算 hash 的文件大小, 來增加hash的計算速度。
缺點:有少許可能照成誤差,對于需精確計算hash則不適用,取舍有寸即可!
例如:
<script> import sparkMD5 from 'spark-md5'export default { methods: {async calculateHashSample() {// this.file 為 e.target.files[0]const spark = new sparkMD5.ArrayBuffer(), reader = new FileReader(),file = this.file, size = file.size, offset = 2 * 1024 * 1024 // hash抽樣: 第一個區塊2M,中間區塊取前中后各2個字節,最后區塊數據全要let chunks = [file.slice(0, offset)]let cur = offsetwhile (cur < size) {if (cur + offset >= size) {chunks.push(file.slice(cur, cur + offset))} else {const mid = cur + offset / 2, end = cur + offsetchunks.push(file.slice(cur, cur + 2))chunks.push(file.slice(mid, mid + 2))chunks.push(file.slice(end - 2, end))}cur += offset}this.chunks = chunks //抽樣后的區塊//下面拿去計算hash就會很快} } </script>總結
以上是生活随笔為你收集整理的js快速计算文件hash值的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信自动挑选黑名单
- 下一篇: 计算机桌面图片唐诗,古诗词高清电脑壁纸