如何在JavaScript中按1KB分片读取文件流?解决全量读取问题
按1KB分片读取文件的解决方案
你的问题出在ByteLengthQueuingStrategy的highWaterMark并不是强制每次读取的分片大小——它只是流内部队列的水位线提示,浏览器底层的文件流实现可能会因为优化(尤其是文件体积较小时)一次性读取整个文件,导致for await循环只执行一次。
要实现严格按1KB分片读取,你可以用以下两种方式解决:
方法1:用FileReader循环读取分片
直接通过File.slice()切割文件,配合FileReader逐块读取:
const file = myFile; const chunkSize = 1024; // 1KB let offset = 0; function readNextChunk() { if (offset >= file.size) return; const chunk = file.slice(offset, offset + chunkSize); const reader = new FileReader(); reader.onload = (e) => { const chunkData = e.target.result; // 可根据需求转成Uint8Array或文本 console.log(chunkData); offset += chunkSize; readNextChunk(); }; reader.onerror = (err) => console.error('分片读取失败:', err); reader.readAsArrayBuffer(chunk); // 也可使用readAsText等方法 } readNextChunk();
方法2:自定义ReadableStream控制分片大小
如果坚持使用流API,可自定义ReadableStream来确保每次输出固定大小的分片:
const file = myFile; const chunkSize = 1024; let offset = 0; const readableStream = new ReadableStream({ async pull(controller) { if (offset >= file.size) { controller.close(); return; } const chunk = file.slice(offset, offset + chunkSize); const buffer = await new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = reject; reader.readAsArrayBuffer(chunk); }); controller.enqueue(new Uint8Array(buffer)); offset += chunkSize; } }); // 遍历自定义流 const stream = []; for await (const chunk of readableStream) { console.log(chunk); // 每次输出1KB的Uint8Array stream.push(chunk); }
原有代码的问题说明
你使用的web-streams-polyfill和适配器仅用于让流支持异步迭代,无法改变浏览器原生File.stream()的读取策略。原生文件流的分片行为由浏览器决定,highWaterMark只是提示流预存数据的阈值,并非强制分片大小。
内容的提问来源于stack exchange,提问作者user5507535
相关产品推荐
相关产品推荐

