1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| class LargeFileStorage { constructor(db, chunkSize = 1024 * 1024) { this.db = db; this.chunkSize = chunkSize; }
const fileId = this.generateId(); const totalChunks = Math.ceil(file.size / this.chunkSize);
id: fileId, name: file.name, size: file.size, type: file.type, totalChunks, uploadedChunks: 0, status: 'uploading', uploadTime: Date.now() });
const start = i * this.chunkSize; const end = Math.min(start + this.chunkSize, file.size); const chunk = file.slice(start, end);
const arrayBuffer = await chunk.arrayBuffer();
await this.db.put('file_chunks', { id: `${fileId}_${i}`, fileId, chunkIndex: i, data: arrayBuffer, size: arrayBuffer.byteLength });
}
}
const metadata = await this.db.get('files_metadata', fileId); if (!metadata || metadata.status !== 'complete') { throw new Error('文件不可用'); }
const chunks = []; for (let i = 0; i < metadata.totalChunks; i++) { const chunk = await this.db.get('file_chunks', `${fileId}_${i}`); if (chunk) { chunks.push(new Uint8Array(chunk.data)); } }
return new Blob([combinedBuffer], { type: metadata.type }); }
async updateUploadProgress(fileId, uploadedChunks) { const metadata = await this.db.get('files_metadata', fileId); await this.db.put('files_metadata', { ...metadata, uploadedChunks, progress: (uploadedChunks / metadata.totalChunks) * 100 }); }
async markUploadComplete(fileId) { const metadata = await this.db.get('files_metadata', fileId); await this.db.put('files_metadata', { ...metadata, status: 'complete', completeTime: Date.now() }); }
generateId() { return Date.now().toString(36) + Math.random().toString(36).substr(2); }
concatenateBuffers(buffers) { const totalLength = buffers.reduce((acc, buf) => acc + buf.length, 0); const result = new Uint8Array(totalLength); let offset = 0;
for (const buffer of buffers) { result.set(buffer, offset); offset += buffer.length; }
return result; } }
|