Simple streaming readline module for Node.js that enables memory-efficient line-by-line file reading
npx @tessl/cli install tessl/npm-linebyline@1.3.00
# LineByLine
1
2
LineByLine is a simple streaming readline module for Node.js that enables memory-efficient line-by-line file reading. It creates a readable stream from a file and emits line events for each line of text, making it ideal for processing large files without loading them entirely into memory.
3
4
## Package Information
5
6
- **Package Name**: linebyline
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install linebyline`
10
11
## Core Imports
12
13
```javascript
14
const readLine = require('linebyline');
15
```
16
17
## Basic Usage
18
19
```javascript
20
const readLine = require('linebyline');
21
22
// Read a file line by line
23
const rl = readLine('./somefile.txt');
24
25
rl.on('line', function(line, lineCount, byteCount) {
26
console.log('Line ' + lineCount + ': ' + line);
27
})
28
.on('error', function(e) {
29
console.error('Error reading file:', e);
30
})
31
.on('end', function() {
32
console.log('Finished reading file');
33
});
34
```
35
36
## Architecture
37
38
LineByLine is built around a simple streaming architecture:
39
40
- **EventEmitter Pattern**: The main class extends EventEmitter to provide event-based line processing
41
- **Stream Integration**: Works with both file paths and existing readable streams
42
- **Memory Efficiency**: Uses a configurable buffer size to read files without loading them entirely into memory
43
- **Line Detection**: Processes data byte-by-byte to detect line endings (LF and CR)
44
- **Error Handling**: Comprehensive error propagation through the event system
45
46
## Capabilities
47
48
### Constructor Function
49
50
Creates a new ReadLine instance for reading files line by line.
51
52
```javascript { .api }
53
/**
54
* Creates a new ReadLine instance for reading files line by line
55
* @param {string|Stream} file - File path string or readable stream object
56
* @param {Object} [opts] - Configuration options
57
* @param {number} [opts.maxLineLength=4096] - Maximum line length in bytes
58
* @param {boolean} [opts.retainBuffer=false] - If true, emits raw Buffer objects instead of strings
59
* @returns {ReadLine} ReadLine instance (EventEmitter)
60
*/
61
function readLine(file, opts);
62
```
63
64
**Usage Examples:**
65
66
```javascript
67
// Basic usage with file path
68
const rl = readLine('./data.txt');
69
70
// With options
71
const rl = readLine('./large-file.txt', {
72
maxLineLength: 8192, // 8K buffer
73
retainBuffer: false // Convert to strings
74
});
75
76
// With existing stream
77
const fs = require('fs');
78
const stream = fs.createReadStream('./file.txt');
79
const rl = readLine(stream);
80
81
// Can be called with or without 'new'
82
const rl1 = readLine('./file.txt');
83
const rl2 = new readLine('./file.txt');
84
```
85
86
### Events
87
88
The ReadLine instance emits several events during file processing.
89
90
#### Line Event
91
92
Emitted for each line read from the file.
93
94
```javascript { .api }
95
/**
96
* Emitted for each line read from the file
97
* @param {string|Buffer} line - Line content (string by default, Buffer if retainBuffer=true)
98
* @param {number} lineCount - Current line number (1-based)
99
* @param {number} byteCount - Total bytes processed so far
100
*/
101
rl.on('line', function(line, lineCount, byteCount) {
102
// Process line
103
});
104
```
105
106
**Usage Examples:**
107
108
```javascript
109
// Standard string processing
110
rl.on('line', function(line, lineCount, byteCount) {
111
console.log(`Line ${lineCount} (${byteCount} bytes): ${line}`);
112
});
113
114
// Custom encoding with retainBuffer
115
const iconv = require('iconv-lite');
116
const rl = readLine('./file-in-win1251.txt', { retainBuffer: true });
117
118
rl.on('line', function(buffer, lineCount, byteCount) {
119
const line = iconv.decode(buffer, 'win1251');
120
console.log(`Decoded line ${lineCount}: ${line}`);
121
});
122
```
123
124
#### Open Event
125
126
Emitted when the underlying file stream opens.
127
128
```javascript { .api }
129
/**
130
* Emitted when the underlying file stream opens
131
* @param {number} fd - File descriptor
132
*/
133
rl.on('open', function(fd) {
134
// File opened successfully
135
});
136
```
137
138
#### Error Event
139
140
Emitted when an error occurs during reading or processing.
141
142
```javascript { .api }
143
/**
144
* Emitted when an error occurs during reading or processing
145
* @param {Error} error - Error object
146
*/
147
rl.on('error', function(error) {
148
// Handle error
149
});
150
```
151
152
**Usage Examples:**
153
154
```javascript
155
rl.on('error', function(err) {
156
if (err.code === 'ENOENT') {
157
console.error('File not found:', err.path);
158
} else {
159
console.error('Reading error:', err.message);
160
}
161
});
162
```
163
164
#### End Event
165
166
Emitted when the file has been completely read.
167
168
```javascript { .api }
169
/**
170
* Emitted when the file has been completely read
171
*/
172
rl.on('end', function() {
173
// File reading completed
174
});
175
```
176
177
#### Close Event
178
179
Emitted when the underlying stream closes.
180
181
```javascript { .api }
182
/**
183
* Emitted when the underlying stream closes
184
*/
185
rl.on('close', function() {
186
// Stream closed
187
});
188
```
189
190
### Configuration Options
191
192
#### maxLineLength
193
194
Controls the maximum buffer size for a single line.
195
196
```javascript { .api }
197
/**
198
* Maximum buffer size for a single line
199
* @type {number}
200
* @default 4096
201
*/
202
opts.maxLineLength
203
```
204
205
Lines longer than this limit will not be read properly and may cause data loss.
206
207
#### retainBuffer
208
209
Controls whether to emit raw Buffer objects instead of converted strings.
210
211
```javascript { .api }
212
/**
213
* When true, the 'line' event receives raw Buffer objects instead of strings
214
* @type {boolean}
215
* @default false
216
*/
217
opts.retainBuffer
218
```
219
220
Useful for custom encoding scenarios where you need to decode the buffer manually.
221
222
**Usage Examples:**
223
224
```javascript
225
// High precision for large lines
226
const rl = readLine('./big-data.txt', {
227
maxLineLength: 16384 // 16K buffer
228
});
229
230
// Custom encoding handling
231
const rl = readLine('./encoded-file.txt', {
232
retainBuffer: true
233
});
234
235
rl.on('line', function(buffer, lineCount, byteCount) {
236
// Custom decoding logic here
237
const line = buffer.toString('utf16le');
238
console.log(line);
239
});
240
```
241
242
## Types
243
244
```javascript { .api }
245
/**
246
* ReadLine class - extends EventEmitter
247
*/
248
class ReadLine extends EventEmitter {
249
constructor(file, opts);
250
251
/** The underlying readable stream */
252
input: ReadableStream;
253
}
254
255
/**
256
* Configuration options for ReadLine constructor
257
*/
258
interface ReadLineOptions {
259
/** Maximum line length in bytes (default: 4096) */
260
maxLineLength?: number;
261
/** If true, emits raw Buffer objects instead of strings (default: false) */
262
retainBuffer?: boolean;
263
}
264
```
265
266
## Error Handling
267
268
LineByLine provides comprehensive error handling through the event system:
269
270
- **File System Errors**: File not found, permission errors, etc. are emitted as 'error' events
271
- **Processing Errors**: Errors during line emission are caught and emitted as 'error' events
272
- **Stream Errors**: Underlying stream errors are propagated through the 'error' event
273
- **Buffer Overflow**: Lines exceeding `maxLineLength` may cause data loss but don't emit errors
274
275
**Best Practices:**
276
277
```javascript
278
const rl = readLine('./file.txt');
279
280
// Always handle errors
281
rl.on('error', function(err) {
282
console.error('Error:', err.message);
283
// Handle error appropriately
284
});
285
286
// Ensure proper cleanup
287
rl.on('end', function() {
288
console.log('Processing completed');
289
});
290
291
rl.on('close', function() {
292
console.log('Stream closed');
293
});
294
```
295
296
## Line Ending Support
297
298
LineByLine handles different line ending formats:
299
300
- **LF (Line Feed - ASCII 10)**: Standard Unix/Linux line endings - triggers line emission
301
- **CR (Carriage Return - ASCII 13)**: Classic Mac line endings - ignored but processed
302
- **CRLF**: Windows line endings work correctly (CR is ignored, LF triggers emission)
303
- **EOF**: Final line is emitted even without trailing line ending
304
305
## Performance Characteristics
306
307
- **Memory Efficient**: Streaming implementation processes files without loading them entirely into memory
308
- **Configurable Buffer**: Default 4K line buffer, adjustable via `maxLineLength` option
309
- **Byte-by-byte Processing**: Processes data one byte at a time for accurate line detection
310
- **Event-driven**: Non-blocking, event-based processing suitable for large files
311
- **Lazy Evaluation**: Lines are processed as they are read from the stream