-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Want a More Modern Version of Your Code? #39
Comments
Well, we used this package for a very long time but the Next.js bundler had some issues with the imports and I had a look at the source code and ended with this rewrite in TypeScript: import fs from 'node:fs';
/**
* New line character.
*/
const NEW_LINE_CODE = '\n'.charCodeAt(0);
/**
* Buffer size to use.
*/
const BUFFER_SIZE = 256;
/**
* Scans the file from the end for lines.
*
* @param file
* @param maxLineCount
* @param encoding
* @returns
*/
async function readLastLinesFromFile(file: fs.promises.FileHandle, maxLineCount: number, encoding?: BufferEncoding): Promise<string> {
const stat = await file.stat();
let remainingBytes = stat.size;
let lineCount = 0;
const prevBuffers: Buffer[] = [];
outer: while (remainingBytes > 0) {
//read a buffer
const bufferLen = Math.min(BUFFER_SIZE, remainingBytes);
const position = remainingBytes - bufferLen;
const { bytesRead, buffer } = await file.read({
buffer: Buffer.alloc(bufferLen),
offset: 0,
length: bufferLen,
position
});
if (bytesRead !== bufferLen) {
throw new Error('read size mismatch');
}
//scan for new line (\n or \r\n)
for (let i = bufferLen - 1; i >= 0; i--) {
if (buffer[i] === NEW_LINE_CODE) {
lineCount++;
//check end condition
if (lineCount >= maxLineCount) {
prevBuffers.push(buffer.subarray(i + 1));
break outer;
}
}
}
prevBuffers.push(buffer);
//next
remainingBytes -= bufferLen;
}
return Buffer.concat(prevBuffers.reverse()).toString(encoding);
}
/**
* Read in the last `n` lines of a file.
*
* Code based on https://github.com/alexbbt/read-last-lines/issues/39.
*
* @param inputFilePath file (direct or relative path to file.)
* @param maxLineCount max number of lines to read in.
* @param encoding
*
* @return a promise resolved with the lines or rejected with an error.
*/
export async function readLastLines(inputFilePath: string, maxLineCount: number, encoding?: BufferEncoding): Promise<string> {
//validate
if (maxLineCount <= 0) {
return '';
}
//scan
let file: fs.promises.FileHandle | undefined;
try {
//open file for reading
file = await fs.promises.open(inputFilePath, 'r');
return await readLastLinesFromFile(file, maxLineCount, encoding);
} finally {
await file?.close();
}
} Feel free to use this version which has several optimizations. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I stole your source code, and then revamped it to use modern JS (eg.
async
/await
). I also changed your snake case variables to camel case, factored a few inner functions outside, etc. (I also eliminated the encoding arg since I didn't need it, but it could easily be restored and I left a note about it in the comments.)Now I completely understand that when someone says "hey I took your great source code and screwed it all up", the original author runs screaming in the opposite :) So feel free to close this ticket without even looking at it ... but just in case you wanted to see my take, I thought I'd share.
Either way though, thanks for making this (small but useful) library :)
The text was updated successfully, but these errors were encountered: