哈希与秒传
ChunkFlow 使用基于内容的哈希来实现通过去重的秒传功能。
工作原理
1. 哈希计算
当选择文件时,ChunkFlow 计算其 MD5 哈希:
typescript
const file = new File(["content"], "file.txt");
const task = manager.createTask(file);
task.on("hashProgress", ({ progress }) => {
console.log(`哈希计算: ${progress}%`);
});
task.on("hashComplete", ({ hash }) => {
console.log(`文件哈希: ${hash}`);
});
await task.start();2. 哈希验证
哈希被发送到服务器以检查文件是否已存在:
typescript
// 服务器检查是否存在具有此哈希的文件
const response = await adapter.verifyHash({
fileHash: "abc123...",
uploadToken: token,
});
if (response.fileExists) {
// 文件已存在 - 秒传!
console.log("文件 URL:", response.fileUrl);
}3. 并行处理
哈希计算和上传同时进行:
选择文件
↓
┌────────────────┬────────────────┐
│ │ │
│ 计算 │ 上传 │
│ 哈希 │ 分片 │
│ (后台) │ (立即) │
│ │ │
└────────────────┴────────────────┘
↓ ↓
哈希完成 分片上传中
↓ ↓
检查是否存在 继续或取消完全秒传
当整个文件已存在时:
typescript
// 第一个用户上传文件
const user1File = new File(["content"], "document.pdf");
await manager.createTask(user1File).start();
// 需要时间上传
// 第二个用户上传相同文件
const user2File = new File(["content"], "document.pdf");
await manager.createTask(user2File).start();
// 立即完成!优势:
- 零上传时间
- 节省带宽
- 减少服务器存储
- 更好的用户体验
部分秒传
当某些分片已存在时:
typescript
// 文件 A:分片 [1, 2, 3, 4, 5]
await manager.createTask(fileA).start();
// 文件 B:分片 [1, 2, 6, 7, 8]
// 只上传分片 [6, 7, 8]
await manager.createTask(fileB).start();优势:
- 更快的上传
- 分片级去重
- 高效存储
- 减少网络使用
配置
启用/禁用哈希计算
typescript
const task = manager.createTask(file, {
enableHash: true, // 默认: true
});哈希算法
ChunkFlow 默认使用 MD5(快速且足以用于去重):
typescript
import { calculateFileHash } from "@chunkflowjs/shared";
const hash = await calculateFileHash(file);
console.log(hash); // MD5 哈希性能
Web Worker
哈希计算在 Web Worker 中运行以避免阻塞主线程:
typescript
// 如果可用,自动使用 Web Worker
const hash = await calculateFileHash(file, (progress) => {
console.log(`进度: ${progress}%`);
});降级方案
如果 Web Workers 不可用,降级到 requestIdleCallback:
typescript
// 在主线程中使用 requestIdleCallback
const hash = await calculateFileHash(file);最佳实践
1. 始终启用哈希
保持哈希计算启用以获得最佳用户体验:
typescript
// 好
const task = manager.createTask(file);
// 除非必要,避免禁用
const task = manager.createTask(file, {
enableHash: false, // 只有在有特定原因时
});2. 显示哈希进度
告知用户哈希计算进度:
typescript
task.on("hashProgress", ({ progress }) => {
updateUI(`准备上传: ${progress}%`);
});
task.on("hashComplete", () => {
updateUI("开始上传...");
});3. 处理秒传
为秒传提供反馈:
typescript
task.on("success", ({ fileUrl }) => {
const wasInstant = task.getProgress().uploadedBytes === 0;
if (wasInstant) {
showMessage("文件已存在 - 秒传!");
} else {
showMessage("上传完成!");
}
});