UNPKG

2.09 kBJavaScriptView Raw
1const fsp = require('fs-promise');
2
3const newLineCharacters = ["\n", "\r"]
4
5const readPreviousChar = function(stat, file, currentCharacterCount) {
6 return fsp.read(file, new Buffer(1), 0, 1, stat.size - 1 - currentCharacterCount)
7 .then((bytesReadAndBuffer) => {
8 return String.fromCharCode(bytesReadAndBuffer[1][0]);
9 })
10}
11
12module.exports = {
13
14 /**
15 * Read in the last `n` lines of a file
16 * @param {string} file direct or relative path to file.
17 * @param {int} maxLineCount max number of lines to read in.
18 * @return {promise} new Promise, resolved with lines or rejected with error.
19 */
20
21 read: function(input_file_path, maxLineCount) {
22 return new Promise((resolve, reject) => {
23 let self = {
24 stat: null,
25 file: null
26 }
27
28 fsp.exists(input_file_path)
29 .then(function(exists) {
30 if (!exists) {
31 throw "file does not exist";
32 }
33
34 }).then(function() {
35 var promises = [];
36
37 // Load file Stats.
38 promises.push(
39 fsp.stat(input_file_path)
40 .then(stat => self.stat = stat));
41
42 // Open file for reading.
43 promises.push(
44 fsp.open(input_file_path, 'r')
45 .then(file => self.file = file));
46
47 return promises;
48 }).then(function(promises) {
49 Promise.all(promises)
50 .then(() => {
51 var chars = 0;
52 var lineCount = 0;
53 var lines = '';
54
55 var do_while_loop = function() {
56 if (lines.length > self.stat.size) {
57 lines = lines.substring(lines.length - self.stat.size);
58 }
59
60 if (lines.length >= self.stat.size || lineCount >= maxLineCount) {
61 if (newLineCharacters.includes(lines.substring(0, 1))) {
62 lines = lines.substring(1);
63 }
64 return resolve(lines);
65 }
66
67 readPreviousChar(self.stat, self.file, chars)
68 .then((nextCharacter) => {
69 lines = nextCharacter + lines;
70 if (newLineCharacters.includes(nextCharacter) && lines.length > 1) {
71 lineCount++;
72 }
73 chars++;
74 })
75 .then(do_while_loop);
76 }
77 do_while_loop();
78
79 });
80 }).catch(reject);
81 })
82 }
83}