1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- // Based on
- // https://gist.github.com/grishgrigoryan/bf6222d16d72cb28620399d27e83eb22
- interface IConfig{
- chunkSize: number;
- }
- const DEFAULT_CHUNK_SIZE: number = 64 * 1024; // 64K
- export class IterableFile implements AsyncIterable<Buffer> {
- private reader: FileReader;
- private file: File
- private config: IConfig = { chunkSize: DEFAULT_CHUNK_SIZE }
- constructor (file: File, config: Partial<IConfig> = {}) {
- this.file = file;
- this.reader = new FileReader();
- Object.assign(this.config, config);
- }
- [Symbol.asyncIterator] () {
- return this.readFile();
- }
- get chunkSize () {
- return this.config.chunkSize;
- }
- get fileSize () {
- return this.file.size;
- }
- readBlobAsBuffer (blob: Blob): Promise<Buffer> {
- return new Promise((resolve, reject) => {
- this.reader.onload = (e) => {
- e.target?.result && resolve(typeof e.target.result === 'string' ? Buffer.from(e.target.result) : Buffer.from(e.target.result));
- e.target?.error && reject(e.target.error);
- };
- this.reader.readAsArrayBuffer(blob);
- });
- }
- async * readFile () {
- let offset = 0;
- let blob;
- let result;
- while (offset < this.fileSize) {
- blob = this.file.slice(offset, this.chunkSize + offset);
- result = await this.readBlobAsBuffer(blob);
- offset += result.length;
- yield result;
- }
- }
- }
- // Usage:
- // let iterableFile = new IterableFile(file)
- // for await (const chunk: Buffer of iterableFile) {
- // doSomethingWithBuffer(chunk)
- // }
|