diff --git a/front/lib/calcFileHash.ts b/front/lib/calcFileHash.ts new file mode 100644 index 0000000..fce71d6 --- /dev/null +++ b/front/lib/calcFileHash.ts @@ -0,0 +1,44 @@ +import SparkMD5 from 'spark-md5'; +import { noop } from 'lodash-es'; + +interface CalcFileHashProps { + file: File; + onProgress?: (current: number) => void; + chunkSize?: number; +} + +const calcFileHash = async (props: CalcFileHashProps) => { + const { file, onProgress = noop, chunkSize = 100 } = props || {}; + 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 => { + return new Promise((resolve, reject) => { + const chunk = file.slice(start, start + chunkSize); + fileReader.onload = (e) => resolve(e.target?.result as ArrayBuffer); + fileReader.onerror = reject; + fileReader.readAsArrayBuffer(chunk); + }); + }; + + try { + const progressCallback = (current: number) => { + const percentage = Math.round((current / chunks) * 100); + onProgress(percentage); + }; + + for (let i = 0; i < chunks; i++) { + const chunk = await readChunk(i * chunkSize); + spark.append(chunk); + progressCallback(i + 1); + } + + return spark.end(); + } catch (error) { + throw error; + } +} + +export default calcFileHash; \ No newline at end of file