Reading lines in JavaScript
readline turns a stream into lines, without loading the file.
import { createReadStream } from "node:fs";
import { mkdtemp, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { createInterface } from "node:readline";
const dir = await mkdtemp(join(tmpdir(), "lines-"));
const path = join(dir, "log.txt");
await writeFile(path, "INFO start\nWARN slow\nINFO done\n");
const lines = createInterface({
input: createReadStream(path),
crlfDelay: Infinity,
});
const counts = new Map();
for await (const line of lines) {
const level = line.split(" ")[0];
counts.set(level, (counts.get(level) ?? 0) + 1);
}
console.log([...counts.entries()].sort());
How it works
crlfDelay: Infinitytreats CRLF as one break.- The interface is async iterable.
- This is how you process a log larger than memory.
Keywords and builtins used here
Mapawaitconstforfromimportof
The run, in numbers
- Lines
- 21
- Characters to type
- 643
- Tokens
- 160
- Three-star pace
- 105 tpm
At the three-star pace of 105 tokens a minute, this run takes about 91 seconds.
Step 2 of 2 in Streams & lines, step 6 of 18 in Node.js.