feat(front): enhance file hash calculation by introducing engine selection for large files using native or wasm methods

This commit is contained in:
keven1024
2026-04-08 23:45:34 +08:00
parent f1dc65b1d0
commit ae2fbcc216
3 changed files with 27 additions and 37 deletions

View File

@@ -137,11 +137,14 @@ watchEffect(async () => {
} }
}) })
const LARGE_FILE_THRESHOLD = 500 * 1024 * 1024 // 500 MB
const handleHash = async (fileId: string) => { const handleHash = async (fileId: string) => {
const uploadfile = uploadfiles.value.find((item) => item.fileId === fileId) const uploadfile = uploadfiles.value.find((item) => item.fileId === fileId)
if (!uploadfile?.file) return if (!uploadfile?.file) return
uploadfile.procressType = 'hash' uploadfile.procressType = 'hash'
const res = await asyncWorker(calcFileHashWorker, { data: { file: uploadfile.file } }) const engine = uploadfile.file.size >= LARGE_FILE_THRESHOLD ? 'wasm' : 'native'
const res = await asyncWorker(calcFileHashWorker, { data: { file: uploadfile.file, engine } })
const { hash } = res?.data || {} const { hash } = res?.data || {}
uploadfile.hash = hash uploadfile.hash = hash
} }

View File

@@ -1,47 +1,34 @@
import { noop } from 'lodash-es' import { noop } from 'lodash-es'
import { md5 } from 'js-md5' import { createSHA1 } from 'hash-wasm'
interface CalcFileHashProps { interface CalcFileHashProps {
file: File file: File
onProgress?: (current: number) => void onProgress?: (current: number) => void
chunkSize?: number chunkSize?: number
engine?: 'native' | 'wasm'
} }
const calcFileHash = async (props: CalcFileHashProps) => { const calcFileHash = async (props: CalcFileHashProps) => {
const { file, onProgress = noop, chunkSize = 100 } = props || {} const { file, onProgress = noop, chunkSize = 100, engine = 'native' } = props || {}
const blob = await file.arrayBuffer()
const hash = md5(blob)
return hash
// const finalChunkSize = chunkSize * 1024 * 1024;
// const chunks = Math.ceil(file.size / finalChunkSize);
// const spark = new SparkMD5.ArrayBuffer(); // 使用 SparkMD5 增量计算哈希
// const fileReader = new FileReader();
// const readChunk = (start: number): Promise<ArrayBuffer> => { if (engine === 'native') {
// return new Promise((resolve, reject) => { const buffer = await file.arrayBuffer()
// const chunk = file.slice(start, Math.min(start + finalChunkSize, file.size)); const hashBuffer = await crypto.subtle.digest('SHA-1', buffer)
// fileReader.onload = (e) => resolve(e.target?.result as ArrayBuffer); return Array.from(new Uint8Array(hashBuffer))
// fileReader.onerror = reject; .map((b) => b.toString(16).padStart(2, '0'))
// fileReader.readAsArrayBuffer(chunk); .join('')
// }); }
// };
// try { const chunkBytes = chunkSize * 1024 * 1024
// const progressCallback = (current: number) => { const hasher = await createSHA1()
// const percentage = Math.round((current / chunks) * 100); let offset = 0
// onProgress(percentage); while (offset < file.size) {
// }; const buffer = await file.slice(offset, offset + chunkBytes).arrayBuffer()
hasher.update(new Uint8Array(buffer))
// for (let i = 0; i < chunks; i++) { offset += chunkBytes
// const chunk = await readChunk(i * chunkSize); onProgress(Math.min(offset, file.size) / file.size)
// spark.append(chunk); }
// progressCallback(i + 1); return hasher.digest('hex')
// }
// return spark.end();
// } catch (error) {
// throw error;
// }
} }
export default calcFileHash export default calcFileHash

View File

@@ -1,8 +1,8 @@
import calcFileHash from './calcFileHash' import calcFileHash from './calcFileHash'
// 监听主线程消息 // 监听主线程消息
self.onmessage = async (e: MessageEvent<{ file: File }>) => { self.onmessage = async (e: MessageEvent<{ file: File; engine?: 'native' | 'wasm' }>) => {
const { file } = e.data || {} const { file, engine } = e.data || {}
const hash = await calcFileHash({ file }) const hash = await calcFileHash({ file, engine })
self.postMessage({ hash }) self.postMessage({ hash })
} }