Skip to content

Instantly share code, notes, and snippets.

@tim-smart
Created December 5, 2024 22:11
Show Gist options
  • Save tim-smart/eeafed1714b2b34cc51c580e185d33ae to your computer and use it in GitHub Desktop.
Save tim-smart/eeafed1714b2b34cc51c580e185d33ae to your computer and use it in GitHub Desktop.
import * as Fs from "node:fs/promises"
export async function* readLinesReverse(path: string, chunkSize = 1024) {
const file = await Fs.open(path, "r")
const stat = await file.stat()
let pos = stat.size
let buffer: Buffer | null = null
while (true) {
pos = Math.max(0, pos - chunkSize)
let chunk = Buffer.alloc(chunkSize)
const result = await file.read(chunk, 0, chunkSize, pos)
pos += chunkSize - result.bytesRead
if (buffer) {
chunk = Buffer.concat([chunk.subarray(0, result.bytesRead), buffer])
buffer = null
} else {
chunk = chunk.subarray(0, result.bytesRead)
}
while (true) {
const newLinePos = chunk.lastIndexOf("\n")
if (newLinePos === -1) {
buffer = chunk
break
}
yield chunk.subarray(newLinePos + 1, chunk.length)
chunk = chunk.subarray(0, newLinePos)
}
if (pos === 0) {
if (chunk.length > 0) yield chunk
break
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment