Skip to content

Commit a2fb3f9

Browse files
authored
fs: add FileHandle.prototype.readLines
PR-URL: nodejs#42590 Reviewed-By: LiviaMedeiros <livia@cirno.name>
1 parent 46a3afb commit a2fb3f9

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

doc/api/fs.md

+41
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,46 @@ If one or more `filehandle.read()` calls are made on a file handle and then a
517517
position till the end of the file. It doesn't always read from the beginning
518518
of the file.
519519
520+
#### `filehandle.readLines([options])`
521+
522+
<!-- YAML
523+
added: REPLACEME
524+
-->
525+
526+
* `options` {Object}
527+
* `encoding` {string} **Default:** `null`
528+
* `autoClose` {boolean} **Default:** `true`
529+
* `emitClose` {boolean} **Default:** `true`
530+
* `start` {integer}
531+
* `end` {integer} **Default:** `Infinity`
532+
* `highWaterMark` {integer} **Default:** `64 * 1024`
533+
* Returns: {readline.InterfaceConstructor}
534+
535+
Convenience method to create a `readline` interface and stream over the file.
536+
See [`filehandle.createReadStream()`][] for the options.
537+
538+
```mjs
539+
import { open } from 'node:fs/promises';
540+
541+
const file = await open('./some/file/to/read');
542+
543+
for await (const line of file.readLines()) {
544+
console.log(line);
545+
}
546+
```
547+
548+
```cjs
549+
const { open } = require('node:fs/promises');
550+
551+
(async () => {
552+
const file = await open('./some/file/to/read');
553+
554+
for await (const line of file.readLines()) {
555+
console.log(line);
556+
}
557+
})();
558+
```
559+
520560
#### `filehandle.readv(buffers[, position])`
521561
522562
<!-- YAML
@@ -7672,6 +7712,7 @@ the file contents.
76727712
[`ReadDirectoryChangesW`]: https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-readdirectorychangesw
76737713
[`UV_THREADPOOL_SIZE`]: cli.md#uv_threadpool_sizesize
76747714
[`event ports`]: https://illumos.org/man/port_create
7715+
[`filehandle.createReadStream()`]: #filehandlecreatereadstreamoptions
76757716
[`filehandle.createWriteStream()`]: #filehandlecreatewritestreamoptions
76767717
[`filehandle.writeFile()`]: #filehandlewritefiledata-options
76777718
[`fs.access()`]: #fsaccesspath-mode-callback

lib/internal/fs/promises.js

+8
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ const kUnref = Symbol('kUnref');
103103
const kLocked = Symbol('kLocked');
104104

105105
const { kUsePromises } = binding;
106+
const { Interface } = require('internal/readline/interface');
106107
const {
107108
JSTransferable, kDeserialize, kTransfer, kTransferList
108109
} = require('internal/worker/js_transferable');
@@ -184,6 +185,13 @@ class FileHandle extends EventEmitterMixin(JSTransferable) {
184185
return fsCall(readFile, this, options);
185186
}
186187

188+
readLines(options = undefined) {
189+
return new Interface({
190+
input: this.createReadStream(options),
191+
crlfDelay: Infinity,
192+
});
193+
}
194+
187195
stat(options) {
188196
return fsCall(fstat, this, options);
189197
}

test/parallel/test-bootstrap-modules.js

+3
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ const expectedModules = new Set([
114114
'NativeModule internal/process/warning',
115115
'NativeModule internal/promise_hooks',
116116
'NativeModule internal/querystring',
117+
'NativeModule internal/readline/callbacks',
118+
'NativeModule internal/readline/interface',
119+
'NativeModule internal/readline/utils',
117120
'NativeModule internal/socketaddress',
118121
'NativeModule internal/source_map/source_map_cache',
119122
'NativeModule internal/stream_base_commons',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import '../common/index.mjs';
2+
import tmpdir from '../common/tmpdir.js';
3+
4+
import assert from 'node:assert';
5+
import { open, writeFile } from 'node:fs/promises';
6+
import path from 'node:path';
7+
8+
tmpdir.refresh();
9+
10+
const filePath = path.join(tmpdir.path, 'file.txt');
11+
12+
await writeFile(filePath, '1\n\n2\n');
13+
14+
let file;
15+
try {
16+
file = await open(filePath);
17+
18+
let i = 0;
19+
for await (const line of file.readLines()) {
20+
switch (i++) {
21+
case 0:
22+
assert.strictEqual(line, '1');
23+
break;
24+
25+
case 1:
26+
assert.strictEqual(line, '');
27+
break;
28+
29+
case 2:
30+
assert.strictEqual(line, '2');
31+
break;
32+
33+
default:
34+
assert.fail();
35+
break;
36+
}
37+
}
38+
} finally {
39+
await file?.close();
40+
}

0 commit comments

Comments
 (0)