| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 51a6afa commit 17c5ede
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -417,6 +417,80 @@ Reads data from the file and stores that in the given buffer. | |||
| 417 | 417 | If the file is not modified concurrently, the end-of-file is reached when the | |
| 418 | 418 | number of bytes read is zero. | |
| 419 | 419 | ||
| 420 | + #### `filehandle.read(buffer[, options])` | ||
| 421 | + | ||
| 422 | + <!-- YAML | ||
| 423 | + added: REPLACEME | ||
| 424 | + --> | ||
| 425 | + | ||
| 426 | + * `buffer` {Buffer|TypedArray|DataView} A buffer that will be filled with the | ||
| 427 | + file data read. | ||
| 428 | + * `options` {Object} | ||
| 429 | + * `offset` {integer} The location in the buffer at which to start filling. | ||
| 430 | + **Default:** `0` | ||
| 431 | + * `length` {integer} The number of bytes to read. **Default:** | ||
| 432 | + `buffer.byteLength - offset` | ||
| 433 | + * `position` {integer} The location where to begin reading data from the | ||
| 434 | + file. If `null`, data will be read from the current file position, and | ||
| 435 | + the position will be updated. If `position` is an integer, the current | ||
| 436 | + file position will remain unchanged. **Default:**: `null` | ||
| 437 | + * Returns: {Promise} Fulfills upon success with an object with two properties: | ||
| 438 | + * `bytesRead` {integer} The number of bytes read | ||
| 439 | + * `buffer` {Buffer|TypedArray|DataView} A reference to the passed in `buffer` | ||
| 440 | + argument. | ||
| 441 | + | ||
| 442 | + Reads data from the file and stores that in the given buffer. | ||
| 443 | + | ||
| 444 | + If the file is not modified concurrently, the end-of-file is reached when the | ||
| 445 | + number of bytes read is zero. | ||
| 446 | + | ||
| 447 | + #### `filehandle.readableWebStream()` | ||
| 448 | + | ||
| 449 | + <!-- YAML | ||
| 450 | + added: v17.0.0 | ||
| 451 | + --> | ||
| 452 | + | ||
| 453 | + > Stability: 1 - Experimental | ||
| 454 | + | ||
| 455 | + * Returns: {ReadableStream} | ||
| 456 | + | ||
| 457 | + Returns a `ReadableStream` that may be used to read the files data. | ||
| 458 | + | ||
| 459 | + An error will be thrown if this method is called more than once or is called | ||
| 460 | + after the `FileHandle` is closed or closing. | ||
| 461 | + | ||
| 462 | + ```mjs | ||
| 463 | + import { | ||
| 464 | + open, | ||
| 465 | + } from 'node:fs/promises'; | ||
| 466 | + | ||
| 467 | + const file = await open('./some/file/to/read'); | ||
| 468 | + | ||
| 469 | + for await (const chunk of file.readableWebStream()) | ||
| 470 | + console.log(chunk); | ||
| 471 | + | ||
| 472 | + await file.close(); | ||
| 473 | + ``` | ||
| 474 | + | ||
| 475 | + ```cjs | ||
| 476 | + const { | ||
| 477 | + open, | ||
| 478 | + } = require('node:fs/promises'); | ||
| 479 | + | ||
| 480 | + (async () => { | ||
| 481 | + const file = await open('./some/file/to/read'); | ||
| 482 | + | ||
| 483 | + for await (const chunk of file.readableWebStream()) | ||
| 484 | + console.log(chunk); | ||
| 485 | + | ||
| 486 | + await file.close(); | ||
| 487 | + })(); | ||
| 488 | + ``` | ||
| 489 | + | ||
| 490 | + While the `ReadableStream` will read the file to completion, it will not | ||
| 491 | + close the `FileHandle` automatically. User code must still call the | ||
| 492 | + `fileHandle.close()` method. | ||
| 493 | + | ||
| 420 | 494 | #### `filehandle.readFile(options)` | |
| 421 | 495 | ||
| 422 | 496 | <!-- YAML | |
@@ -3058,6 +3132,28 @@ Similar to the [`fs.read()`][] function, this version takes an optional | |||
| 3058 | 3132 | `options` object. If no `options` object is specified, it will default with the | |
| 3059 | 3133 | above values. | |
| 3060 | 3134 | ||
| 3135 | + ### `fs.read(fd, buffer[, options], callback)` | ||
| 3136 | + | ||
| 3137 | + <!-- YAML | ||
| 3138 | + added: REPLACEME | ||
| 3139 | + --> | ||
| 3140 | + | ||
| 3141 | + * `fd` {integer} | ||
| 3142 | + * `buffer` {Buffer|TypedArray|DataView} The buffer that the data will be | ||
| 3143 | + written to. | ||
| 3144 | + * `options` {Object} | ||
| 3145 | + * `offset` {integer} **Default:** `0` | ||
| 3146 | + * `length` {integer} **Default:** `buffer.byteLength - offset` | ||
| 3147 | + * `position` {integer|bigint} **Default:** `null` | ||
| 3148 | + * `callback` {Function} | ||
| 3149 | + * `err` {Error} | ||
| 3150 | + * `bytesRead` {integer} | ||
| 3151 | + * `buffer` {Buffer} | ||
| 3152 | + | ||
| 3153 | + Similar to the [`fs.read()`][] function, this version takes an optional | ||
| 3154 | + `options` object. If no `options` object is specified, it will default with the | ||
| 3155 | + above values. | ||
| 3156 | + | ||
| 3061 | 3157 | ### `fs.readdir(path[, options], callback)` | |
| 3062 | 3158 | ||
| 3063 | 3159 | <!-- YAML | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -137,6 +137,7 @@ const { | |||
| 137 | 137 | validateEncoding, | |
| 138 | 138 | validateFunction, | |
| 139 | 139 | validateInteger, | |
| 140 | + validateObject, | ||
| 140 | 141 | validateString, | |
| 141 | 142 | } = require('internal/validators'); | |
| 142 | 143 | ||
@@ -591,7 +592,7 @@ function openSync(path, flags, mode) { | |||
| 591 | 592 | * Reads file from the specified `fd` (file descriptor). | |
| 592 | 593 | * @param {number} fd | |
| 593 | 594 | * @param {Buffer | TypedArray | DataView} buffer | |
| 594 | - * @param {number} offset | ||
| 595 | + * @param {number} offsetOrOptions | ||
| 595 | 596 | * @param {number} length | |
| 596 | 597 | * @param {number | bigint | null} position | |
| 597 | 598 | * @param {( | |
@@ -601,30 +602,36 @@ function openSync(path, flags, mode) { | |||
| 601 | 602 | * ) => any} callback | |
| 602 | 603 | * @returns {void} | |
| 603 | 604 | */ | |
| 604 | - function read(fd, buffer, offset, length, position, callback) { | ||
| 605 | + function read(fd, buffer, offsetOrOptions, length, position, callback) { | ||
| 605 | 606 | fd = getValidatedFd(fd); | |
| 606 | 607 | ||
| 607 | - if (arguments.length <= 3) { | ||
| 608 | - // Assume fs.read(fd, options, callback) | ||
| 609 | - let options = ObjectCreate(null); | ||
| 610 | - if (arguments.length < 3) { | ||
| 608 | + let offset = offsetOrOptions; | ||
| 609 | + let params = null; | ||
| 610 | + if (arguments.length <= 4) { | ||
| 611 | + if (arguments.length === 4) { | ||
| 612 | + // This is fs.read(fd, buffer, options, callback) | ||
| 613 | + validateObject(offsetOrOptions, 'options', { nullable: true }); | ||
| 614 | + callback = length; | ||
| 615 | + params = offsetOrOptions; | ||
| 616 | + } else if (arguments.length === 3) { | ||
| 617 | + // This is fs.read(fd, bufferOrParams, callback) | ||
| 618 | + if (!isArrayBufferView(buffer)) { | ||
| 619 | + // This is fs.read(fd, params, callback) | ||
| 620 | + params = buffer; | ||
| 621 | + ({ buffer = Buffer.alloc(16384) } = params ?? ObjectCreate(null)); | ||
| 622 | + } | ||
| 623 | + callback = offsetOrOptions; | ||
| 624 | + } else { | ||
| 611 | 625 | // This is fs.read(fd, callback) | |
| 612 | - // buffer will be the callback | ||
| 613 | 626 | callback = buffer; | |
| 614 | - } else { | ||
| 615 | - // This is fs.read(fd, {}, callback) | ||
| 616 | - // buffer will be the options object | ||
| 617 | - // offset is the callback | ||
| 618 | - options = buffer; | ||
| 619 | - callback = offset; | ||
| 627 | + buffer = Buffer.alloc(16384); | ||
| 620 | 628 | } | |
| 621 | 629 | ||
| 622 | 630 | ({ | |
| 623 | - buffer = Buffer.alloc(16384), | ||
| 624 | 631 | offset = 0, | |
| 625 | 632 | length = buffer.byteLength - offset, | |
| 626 | 633 | position = null | |
| 627 | - } = options); | ||
| 634 | + } = params ?? ObjectCreate(null)); | ||
| 628 | 635 | } | |
| 629 | 636 | ||
| 630 | 637 | validateBuffer(buffer); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -456,20 +456,29 @@ async function open(path, flags, mode) { | |||
| 456 | 456 | flagsNumber, mode, kUsePromises)); | |
| 457 | 457 | } | |
| 458 | 458 | ||
| 459 | - async function read(handle, bufferOrOptions, offset, length, position) { | ||
| 460 | - let buffer = bufferOrOptions; | ||
| 459 | + async function read(handle, bufferOrParams, offset, length, position) { | ||
| 460 | + let buffer = bufferOrParams; | ||
| 461 | 461 | if (!isArrayBufferView(buffer)) { | |
| 462 | - bufferOrOptions ??= ObjectCreate(null); | ||
| 462 | + // This is fh.read(params) | ||
| 463 | 463 | ({ | |
| 464 | 464 | buffer = Buffer.alloc(16384), | |
| 465 | 465 | offset = 0, | |
| 466 | 466 | length = buffer.byteLength - offset, | |
| 467 | 467 | position = null | |
| 468 | - } = bufferOrOptions); | ||
| 468 | + } = bufferOrParams ?? ObjectCreate(null)); | ||
| 469 | 469 | ||
| 470 | 470 | validateBuffer(buffer); | |
| 471 | 471 | } | |
| 472 | 472 | ||
| 473 | + if (offset !== null && typeof offset === 'object') { | ||
| 474 | + // This is fh.read(buffer, options) | ||
| 475 | + ({ | ||
| 476 | + offset = 0, | ||
| 477 | + length = buffer.byteLength - offset, | ||
| 478 | + position = null | ||
| 479 | + } = offset ?? ObjectCreate(null)); | ||
| 480 | + } | ||
| 481 | + | ||
| 473 | 482 | if (offset == null) { | |
| 474 | 483 | offset = 0; | |
| 475 | 484 | } else { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,29 +14,51 @@ const filepath = fixtures.path('x.txt'); | |||
| 14 | 14 | const buf = Buffer.alloc(1); | |
| 15 | 15 | // Reading only one character, hence buffer of one byte is enough. | |
| 16 | 16 | ||
| 17 | - // Test for callback API. | ||
| 17 | + // Tests are done by making sure the first letter in buffer is | ||
| 18 | + // same as first letter in file. | ||
| 19 | + // 120 is the ascii code of letter x. | ||
| 20 | + | ||
| 21 | + // Tests for callback API. | ||
| 18 | 22 | fs.open(filepath, 'r', common.mustSucceed((fd) => { | |
| 19 | 23 | fs.read(fd, { offset: null, buffer: buf }, | |
| 20 | 24 | common.mustSucceed((bytesRead, buffer) => { | |
| 21 | - // Test is done by making sure the first letter in buffer is | ||
| 22 | - // same as first letter in file. | ||
| 23 | - // 120 is the hex for ascii code of letter x. | ||
| 25 | + assert.strictEqual(buffer[0], 120); | ||
| 26 | + fs.close(fd, common.mustSucceed(() => {})); | ||
| 27 | + })); | ||
| 28 | + })); | ||
| 29 | + | ||
| 30 | + fs.open(filepath, 'r', common.mustSucceed((fd) => { | ||
| 31 | + fs.read(fd, buf, { offset: null }, | ||
| 32 | + common.mustSucceed((bytesRead, buffer) => { | ||
| 24 | 33 | assert.strictEqual(buffer[0], 120); | |
| 25 | 34 | fs.close(fd, common.mustSucceed(() => {})); | |
| 26 | 35 | })); | |
| 27 | 36 | })); | |
| 28 | 37 | ||
| 29 | 38 | let filehandle = null; | |
| 30 | 39 | ||
| 31 | - // Test for promise api | ||
| 40 | + // Tests for promises api | ||
| 41 | + (async () => { | ||
| 42 | + filehandle = await fsPromises.open(filepath, 'r'); | ||
| 43 | + const readObject = await filehandle.read(buf, { offset: null }); | ||
| 44 | + assert.strictEqual(readObject.buffer[0], 120); | ||
| 45 | + })() | ||
| 46 | + .finally(() => filehandle?.close()) | ||
| 47 | + .then(common.mustCall()); | ||
| 48 | + | ||
| 49 | + // Undocumented: omitted position works the same as position === null | ||
| 32 | 50 | (async () => { | |
| 33 | 51 | filehandle = await fsPromises.open(filepath, 'r'); | |
| 34 | 52 | const readObject = await filehandle.read(buf, null, buf.length); | |
| 35 | 53 | assert.strictEqual(readObject.buffer[0], 120); | |
| 36 | 54 | })() | |
| 37 | - .then(common.mustCall()) | ||
| 38 | - .finally(async () => { | ||
| 39 | - // Close the file handle if it is opened | ||
| 40 | - if (filehandle) | ||
| 41 | - await filehandle.close(); | ||
| 42 | - }); | ||
| 55 | + .finally(() => filehandle?.close()) | ||
| 56 | + .then(common.mustCall()); | ||
| 57 | + | ||
| 58 | + (async () => { | ||
| 59 | + filehandle = await fsPromises.open(filepath, 'r'); | ||
| 60 | + const readObject = await filehandle.read(buf, null, buf.length, 0); | ||
| 61 | + assert.strictEqual(readObject.buffer[0], 120); | ||
| 62 | + })() | ||
| 63 | + .finally(() => filehandle?.close()) | ||
| 64 | + .then(common.mustCall()); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,32 +5,34 @@ const fixtures = require('../common/fixtures'); | |||
| 5 | 5 | const fs = require('fs'); | |
| 6 | 6 | const assert = require('assert'); | |
| 7 | 7 | const filepath = fixtures.path('x.txt'); | |
| 8 | - const fd = fs.openSync(filepath, 'r'); | ||
| 9 | 8 | ||
| 10 | 9 | const expected = Buffer.from('xyz\n'); | |
| 11 | 10 | const defaultBufferAsync = Buffer.alloc(16384); | |
| 12 | - const bufferAsOption = Buffer.allocUnsafe(expected.length); | ||
| 11 | + const bufferAsOption = Buffer.allocUnsafe(expected.byteLength); | ||
| 13 | 12 | ||
| 14 | - // Test not passing in any options object | ||
| 15 | - fs.read(fd, common.mustCall((err, bytesRead, buffer) => { | ||
| 16 | - assert.strictEqual(bytesRead, expected.length); | ||
| 17 | - assert.deepStrictEqual(defaultBufferAsync.length, buffer.length); | ||
| 18 | - })); | ||
| 13 | + function testValid(message, ...options) { | ||
| 14 | + const paramsMsg = `${message} (as params)`; | ||
| 15 | + const paramsFilehandle = fs.openSync(filepath, 'r'); | ||
| 16 | + fs.read(paramsFilehandle, ...options, common.mustSucceed((bytesRead, buffer) => { | ||
| 17 | + assert.strictEqual(bytesRead, expected.byteLength, paramsMsg); | ||
| 18 | + assert.deepStrictEqual(defaultBufferAsync.byteLength, buffer.byteLength, paramsMsg); | ||
| 19 | + fs.closeSync(paramsFilehandle); | ||
| 20 | + })); | ||
| 19 | 21 | ||
| 20 | - // Test passing in an empty options object | ||
| 21 | - fs.read(fd, { position: 0 }, common.mustCall((err, bytesRead, buffer) => { | ||
| 22 | - assert.strictEqual(bytesRead, expected.length); | ||
| 23 | - assert.deepStrictEqual(defaultBufferAsync.length, buffer.length); | ||
| 24 | - })); | ||
| 22 | + const optionsMsg = `${message} (as options)`; | ||
| 23 | + const optionsFilehandle = fs.openSync(filepath, 'r'); | ||
| 24 | + fs.read(optionsFilehandle, bufferAsOption, ...options, common.mustSucceed((bytesRead, buffer) => { | ||
| 25 | + assert.strictEqual(bytesRead, expected.byteLength, optionsMsg); | ||
| 26 | + assert.deepStrictEqual(bufferAsOption.byteLength, buffer.byteLength, optionsMsg); | ||
| 27 | + fs.closeSync(optionsFilehandle); | ||
| 28 | + })); | ||
| 29 | + } | ||
| 25 | 30 | ||
| 26 | - // Test passing in options | ||
| 27 | - fs.read(fd, { | ||
| 28 | - buffer: bufferAsOption, | ||
| 31 | + testValid('Not passing in any object'); | ||
| 32 | + testValid('Passing in a null', null); | ||
| 33 | + testValid('Passing in an empty object', {}); | ||
| 34 | + testValid('Passing in an object', { | ||
| 29 | 35 | offset: 0, | |
| 30 | - length: bufferAsOption.length, | ||
| 31 | - position: 0 | ||
| 32 | - }, | ||
| 33 | - common.mustCall((err, bytesRead, buffer) => { | ||
| 34 | - assert.strictEqual(bytesRead, expected.length); | ||
| 35 | - assert.deepStrictEqual(bufferAsOption.length, buffer.length); | ||
| 36 | - })); | ||
| 36 | + length: bufferAsOption.byteLength, | ||
| 37 | + position: 0, | ||
| 38 | + }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,10 +10,18 @@ const fd = fs.openSync(filepath, 'r'); | |||
| 10 | 10 | ||
| 11 | 11 | const expected = Buffer.from('xyz\n'); | |
| 12 | 12 | const defaultBufferAsync = Buffer.alloc(16384); | |
| 13 | + const bufferAsOption = Buffer.allocUnsafe(expected.byteLength); | ||
| 13 | 14 | ||
| 14 | 15 | read(fd, {}) | |
| 15 | 16 | .then(function({ bytesRead, buffer }) { | |
| 16 | - assert.strictEqual(bytesRead, expected.length); | ||
| 17 | - assert.deepStrictEqual(defaultBufferAsync.length, buffer.length); | ||
| 17 | + assert.strictEqual(bytesRead, expected.byteLength); | ||
| 18 | + assert.deepStrictEqual(defaultBufferAsync.byteLength, buffer.byteLength); | ||
| 19 | + }) | ||
| 20 | + .then(common.mustCall()); | ||
| 21 | + | ||
| 22 | + read(fd, bufferAsOption, { position: 0 }) | ||
| 23 | + .then(function({ bytesRead, buffer }) { | ||
| 24 | + assert.strictEqual(bytesRead, expected.byteLength); | ||
| 25 | + assert.deepStrictEqual(bufferAsOption.byteLength, buffer.byteLength); | ||
| 18 | 26 | }) | |
| 19 | 27 | .then(common.mustCall()); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments