generator 本身不直接读取文件,但可通过封装 readablestream 实现按需逐行消费;推荐使用 async generator(node.js ≥10.0),配合 fs.createreadstream 和 readline.createinterface,以 for await...of 拉取每一行,避免内存溢出。

Generator 本身不直接读取文件,但它能配合异步操作(如 fs.createReadStream 或 fetch 流)实现“按需逐行消费”的逻辑,核心是把流式数据封装成可暂停、可恢复的迭代器。下面用 Node.js 环境模拟大文件逐行读取的关键思路和代码结构。
用 Generator 封装 ReadableStream 的行迭代器
Node.js 的 readline 模块天然支持按行读取流,结合 AsyncIterator(或手动包装为同步 Generator + 异步驱动)可让调用方以类似 for...of 的方式“拉取”每一行:
- 不把整个文件加载进内存,而是通过流(
fs.createReadStream)分块传输 - 用
readline.createInterface绑定流,监听'line'事件 - Generator 内部用
yield暂停,等待下一行就绪后继续 —— 实际需搭配Promise和async/await驱动(标准 Generator 是同步的,所以常使用 async generator)
推荐写法:使用 async generator(Node.js ≥ 10.0)
这是最自然、符合直觉的方式。async generator 返回 AsyncIterator,可直接用 for await...of 消费:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
import * as fs from 'fs';
import * as readline from 'readline';
<p>async function* readLines(filename) {
const fileStream = fs.createReadStream(filename, { encoding: 'utf8' });
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});</p><p>for await (const line of rl) {
yield line; // 每次 yield 一行,自动暂停等待下一次迭代
}
}</p><p>// 使用示例
async function processBigFile() {
for await (const line of readLines('./huge.log')) {
console.log('处理行:', line.slice(0, 50));
// 可在此加入过滤、解析、限速等逻辑
}
}
</p>
如果必须用普通 sync Generator(仅作逻辑模拟)
纯同步 Generator 无法真正“等待”文件 I/O,但可用于模拟逐行生成行为(比如从数组或预加载的小样本中 fake 数据),帮助理解控制流:
function* mockLineReader(lines) {
for (let i = 0; i // 使用
const reader = mockLineReader(['line1', 'line2', 'line3']);
console.log(reader.next().value); // 'line1'
console.log(reader.next().value); // 'line2'
⚠️ 注意:这种写法不能替代真实大文件读取,它只是 Generator 控制权移交的示意。
关键注意事项
- 不要在普通 Generator 中做 fs.readFileSync:会阻塞主线程,失去“逐行”意义,也违背流式初衷
-
行编码与换行符要一致:确保文件是 UTF-8,且
crlfDelay: Infinity能正确处理\r\n和\n -
错误需透出:在 async generator 中监听
fileStream.on('error')并 throw,避免静默失败 -
资源需手动清理(必要时):大文件处理长时间运行时,可监听
return()方法关闭流(需在 generator 内实现[Symbol.asyncIterator]的完整协议)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










