| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent a37527c commit c7f3294
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -230,6 +230,99 @@ try { | |||
| 230 | 230 | } | |
| 231 | 231 | ``` | |
| 232 | 232 | ||
| 233 | + #### `filehandle.createReadStream([options])` | ||
| 234 | + <!-- YAML | ||
| 235 | + added: REPLACEME | ||
| 236 | + --> | ||
| 237 | + | ||
| 238 | + * `options` {Object} | ||
| 239 | + * `encoding` {string} **Default:** `null` | ||
| 240 | + * `autoClose` {boolean} **Default:** `true` | ||
| 241 | + * `emitClose` {boolean} **Default:** `true` | ||
| 242 | + * `start` {integer} | ||
| 243 | + * `end` {integer} **Default:** `Infinity` | ||
| 244 | + * `highWaterMark` {integer} **Default:** `64 * 1024` | ||
| 245 | + * Returns: {fs.ReadStream} | ||
| 246 | + | ||
| 247 | + Unlike the 16 kb default `highWaterMark` for a {stream.Readable}, the stream | ||
| 248 | + returned by this method has a default `highWaterMark` of 64 kb. | ||
| 249 | + | ||
| 250 | + `options` can include `start` and `end` values to read a range of bytes from | ||
| 251 | + the file instead of the entire file. Both `start` and `end` are inclusive and | ||
| 252 | + start counting at 0, allowed values are in the | ||
| 253 | + [0, [`Number.MAX_SAFE_INTEGER`][]] range. If `start` is | ||
| 254 | + omitted or `undefined`, `filehandle.createReadStream()` reads sequentially from | ||
| 255 | + the current file position. The `encoding` can be any one of those accepted by | ||
| 256 | + {Buffer}. | ||
| 257 | + | ||
| 258 | + If the `FileHandle` points to a character device that only supports blocking | ||
| 259 | + reads (such as keyboard or sound card), read operations do not finish until data | ||
| 260 | + is available. This can prevent the process from exiting and the stream from | ||
| 261 | + closing naturally. | ||
| 262 | + | ||
| 263 | + By default, the stream will emit a `'close'` event after it has been | ||
| 264 | + destroyed. Set the `emitClose` option to `false` to change this behavior. | ||
| 265 | + | ||
| 266 | + ```mjs | ||
| 267 | + import { open } from 'fs/promises'; | ||
| 268 | + | ||
| 269 | + const fd = await open('/dev/input/event0'); | ||
| 270 | + // Create a stream from some character device. | ||
| 271 | + const stream = fd.createReadStream(); | ||
| 272 | + setTimeout(() => { | ||
| 273 | + stream.close(); // This may not close the stream. | ||
| 274 | + // Artificially marking end-of-stream, as if the underlying resource had | ||
| 275 | + // indicated end-of-file by itself, allows the stream to close. | ||
| 276 | + // This does not cancel pending read operations, and if there is such an | ||
| 277 | + // operation, the process may still not be able to exit successfully | ||
| 278 | + // until it finishes. | ||
| 279 | + stream.push(null); | ||
| 280 | + stream.read(0); | ||
| 281 | + }, 100); | ||
| 282 | + ``` | ||
| 283 | + | ||
| 284 | + If `autoClose` is false, then the file descriptor won't be closed, even if | ||
| 285 | + there's an error. It is the application's responsibility to close it and make | ||
| 286 | + sure there's no file descriptor leak. If `autoClose` is set to true (default | ||
| 287 | + behavior), on `'error'` or `'end'` the file descriptor will be closed | ||
| 288 | + automatically. | ||
| 289 | + | ||
| 290 | + An example to read the last 10 bytes of a file which is 100 bytes long: | ||
| 291 | + | ||
| 292 | + ```mjs | ||
| 293 | + import { open } from 'fs/promises'; | ||
| 294 | + | ||
| 295 | + const fd = await open('sample.txt'); | ||
| 296 | + fd.createReadStream({ start: 90, end: 99 }); | ||
| 297 | + ``` | ||
| 298 | + | ||
| 299 | + #### `filehandle.createWriteStream([options])` | ||
| 300 | + <!-- YAML | ||
| 301 | + added: REPLACEME | ||
| 302 | + --> | ||
| 303 | + | ||
| 304 | + * `options` {Object} | ||
| 305 | + * `encoding` {string} **Default:** `'utf8'` | ||
| 306 | + * `autoClose` {boolean} **Default:** `true` | ||
| 307 | + * `emitClose` {boolean} **Default:** `true` | ||
| 308 | + * `start` {integer} | ||
| 309 | + * Returns: {fs.WriteStream} | ||
| 310 | + | ||
| 311 | + `options` may also include a `start` option to allow writing data at some | ||
| 312 | + position past the beginning of the file, allowed values are in the | ||
| 313 | + [0, [`Number.MAX_SAFE_INTEGER`][]] range. Modifying a file rather than replacing | ||
| 314 | + it may require the `flags` `open` option to be set to `r+` rather than the | ||
| 315 | + default `r`. The `encoding` can be any one of those accepted by {Buffer}. | ||
| 316 | + | ||
| 317 | + If `autoClose` is set to true (default behavior) on `'error'` or `'finish'` | ||
| 318 | + the file descriptor will be closed automatically. If `autoClose` is false, | ||
| 319 | + then the file descriptor won't be closed, even if there's an error. | ||
| 320 | + It is the application's responsibility to close it and make sure there's no | ||
| 321 | + file descriptor leak. | ||
| 322 | + | ||
| 323 | + By default, the stream will emit a `'close'` event after it has been | ||
| 324 | + destroyed. Set the `emitClose` option to `false` to change this behavior. | ||
| 325 | + | ||
| 233 | 326 | #### `filehandle.datasync()` | |
| 234 | 327 | <!-- YAML | |
| 235 | 328 | added: v10.0.0 | |
@@ -1937,9 +2030,9 @@ changes: | |||
| 1937 | 2030 | * `end` {integer} **Default:** `Infinity` | |
| 1938 | 2031 | * `highWaterMark` {integer} **Default:** `64 * 1024` | |
| 1939 | 2032 | * `fs` {Object|null} **Default:** `null` | |
| 1940 | - * Returns: {fs.ReadStream} See [Readable Stream][]. | ||
| 2033 | + * Returns: {fs.ReadStream} | ||
| 1941 | 2034 | ||
| 1942 | - Unlike the 16 kb default `highWaterMark` for a readable stream, the stream | ||
| 2035 | + Unlike the 16 kb default `highWaterMark` for a {stream.Readable}, the stream | ||
| 1943 | 2036 | returned by this method has a default `highWaterMark` of 64 kb. | |
| 1944 | 2037 | ||
| 1945 | 2038 | `options` can include `start` and `end` values to read a range of bytes from | |
@@ -1961,8 +2054,7 @@ available. This can prevent the process from exiting and the stream from | |||
| 1961 | 2054 | closing naturally. | |
| 1962 | 2055 | ||
| 1963 | 2056 | By default, the stream will emit a `'close'` event after it has been | |
| 1964 | - destroyed, like most `Readable` streams. Set the `emitClose` option to | ||
| 1965 | - `false` to change this behavior. | ||
| 2057 | + destroyed. Set the `emitClose` option to `false` to change this behavior. | ||
| 1966 | 2058 | ||
| 1967 | 2059 | By providing the `fs` option, it is possible to override the corresponding `fs` | |
| 1968 | 2060 | implementations for `open`, `read`, and `close`. When providing the `fs` option, | |
@@ -2058,7 +2150,7 @@ changes: | |||
| 2058 | 2150 | * `emitClose` {boolean} **Default:** `true` | |
| 2059 | 2151 | * `start` {integer} | |
| 2060 | 2152 | * `fs` {Object|null} **Default:** `null` | |
| 2061 | - * Returns: {fs.WriteStream} See [Writable Stream][]. | ||
| 2153 | + * Returns: {fs.WriteStream} | ||
| 2062 | 2154 | ||
| 2063 | 2155 | `options` may also include a `start` option to allow writing data at some | |
| 2064 | 2156 | position past the beginning of the file, allowed values are in the | |
@@ -2073,8 +2165,7 @@ It is the application's responsibility to close it and make sure there's no | |||
| 2073 | 2165 | file descriptor leak. | |
| 2074 | 2166 | ||
| 2075 | 2167 | By default, the stream will emit a `'close'` event after it has been | |
| 2076 | - destroyed, like most `Writable` streams. Set the `emitClose` option to | ||
| 2077 | - `false` to change this behavior. | ||
| 2168 | + destroyed. Set the `emitClose` option to `false` to change this behavior. | ||
| 2078 | 2169 | ||
| 2079 | 2170 | By providing the `fs` option it is possible to override the corresponding `fs` | |
| 2080 | 2171 | implementations for `open`, `write`, `writev` and `close`. Overriding `write()` | |
@@ -6867,8 +6958,6 @@ the file contents. | |||
| 6867 | 6958 | [MSDN-Rel-Path]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#fully-qualified-vs-relative-paths | |
| 6868 | 6959 | [MSDN-Using-Streams]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/using-streams | |
| 6869 | 6960 | [Naming Files, Paths, and Namespaces]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file | |
| 6870 | - [Readable Stream]: stream.md#stream_class_stream_readable | ||
| 6871 | - [Writable Stream]: stream.md#stream_class_stream_writable | ||
| 6872 | 6961 | [`AHAFS`]: https://developer.ibm.com/articles/au-aix_event_infrastructure/ | |
| 6873 | 6962 | [`Buffer.byteLength`]: buffer.md#buffer_static_method_buffer_bytelength_string_encoding | |
| 6874 | 6963 | [`FSEvents`]: https://developer.apple.com/documentation/coreservices/file_system_events | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -103,6 +103,12 @@ function lazyLoadCpPromises() { | |||
| 103 | 103 | return cpPromises ??= require('internal/fs/cp/cp').cpFn; | |
| 104 | 104 | } | |
| 105 | 105 | ||
| 106 | + // Lazy loaded to avoid circular dependency. | ||
| 107 | + let fsStreams; | ||
| 108 | + function lazyFsStreams() { | ||
| 109 | + return fsStreams ??= require('internal/fs/streams'); | ||
| 110 | + } | ||
| 111 | + | ||
| 106 | 112 | class FileHandle extends EventEmitterMixin(JSTransferable) { | |
| 107 | 113 | /** | |
| 108 | 114 | * @param {InternalFSBinding.FileHandle | undefined} filehandle | |
@@ -213,6 +219,40 @@ class FileHandle extends EventEmitterMixin(JSTransferable) { | |||
| 213 | 219 | return this[kClosePromise]; | |
| 214 | 220 | } | |
| 215 | 221 | ||
| 222 | + /** | ||
| 223 | + * @typedef {import('./streams').ReadStream | ||
| 224 | + * } ReadStream | ||
| 225 | + * @param {{ | ||
| 226 | + * encoding?: string; | ||
| 227 | + * autoClose?: boolean; | ||
| 228 | + * emitClose?: boolean; | ||
| 229 | + * start: number; | ||
| 230 | + * end?: number; | ||
| 231 | + * highWaterMark?: number; | ||
| 232 | + * }} [options] | ||
| 233 | + * @returns {ReadStream} | ||
| 234 | + */ | ||
| 235 | + createReadStream(options = undefined) { | ||
| 236 | + const { ReadStream } = lazyFsStreams(); | ||
| 237 | + return new ReadStream(undefined, { ...options, fd: this }); | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + /** | ||
| 241 | + * @typedef {import('./streams').WriteStream | ||
| 242 | + * } WriteStream | ||
| 243 | + * @param {{ | ||
| 244 | + * encoding?: string; | ||
| 245 | + * autoClose?: boolean; | ||
| 246 | + * emitClose?: boolean; | ||
| 247 | + * start: number; | ||
| 248 | + * }} [options] | ||
| 249 | + * @returns {WriteStream} | ||
| 250 | + */ | ||
| 251 | + createWriteStream(options = undefined) { | ||
| 252 | + const { WriteStream } = lazyFsStreams(); | ||
| 253 | + return new WriteStream(undefined, { ...options, fd: this }); | ||
| 254 | + } | ||
| 255 | + | ||
| 216 | 256 | [kTransfer]() { | |
| 217 | 257 | if (this[kClosePromise] || this[kRefs] > 1) { | |
| 218 | 258 | throw lazyDOMException('Cannot transfer FileHandle while in use', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,48 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + | ||
| 5 | + // The following tests validate base functionality for the fs.promises | ||
| 6 | + // FileHandle.write method. | ||
| 7 | + | ||
| 8 | + const fs = require('fs'); | ||
| 9 | + const { open } = fs.promises; | ||
| 10 | + const path = require('path'); | ||
| 11 | + const tmpdir = require('../common/tmpdir'); | ||
| 12 | + const assert = require('assert'); | ||
| 13 | + const { finished } = require('stream/promises'); | ||
| 14 | + const { buffer } = require('stream/consumers'); | ||
| 15 | + const tmpDir = tmpdir.path; | ||
| 16 | + | ||
| 17 | + tmpdir.refresh(); | ||
| 18 | + | ||
| 19 | + async function validateWrite() { | ||
| 20 | + const filePathForHandle = path.resolve(tmpDir, 'tmp-write.txt'); | ||
| 21 | + const fileHandle = await open(filePathForHandle, 'w'); | ||
| 22 | + const buffer = Buffer.from('Hello world'.repeat(100), 'utf8'); | ||
| 23 | + | ||
| 24 | + const stream = fileHandle.createWriteStream(); | ||
| 25 | + stream.end(buffer); | ||
| 26 | + await finished(stream); | ||
| 27 | + | ||
| 28 | + const readFileData = fs.readFileSync(filePathForHandle); | ||
| 29 | + assert.deepStrictEqual(buffer, readFileData); | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + async function validateRead() { | ||
| 33 | + const filePathForHandle = path.resolve(tmpDir, 'tmp-read.txt'); | ||
| 34 | + const buf = Buffer.from('Hello world'.repeat(100), 'utf8'); | ||
| 35 | + | ||
| 36 | + fs.writeFileSync(filePathForHandle, buf); | ||
| 37 | + | ||
| 38 | + const fileHandle = await open(filePathForHandle); | ||
| 39 | + assert.deepStrictEqual( | ||
| 40 | + await buffer(fileHandle.createReadStream()), | ||
| 41 | + buf | ||
| 42 | + ); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + Promise.all([ | ||
| 46 | + validateWrite(), | ||
| 47 | + validateRead(), | ||
| 48 | + ]).then(common.mustCall()); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments