From 307c1d817f2fac5e65f0978219ba43db6e2ecdca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Sun, 8 Aug 2021 17:07:27 +0200 Subject: [PATCH] doc: refactor fs docs structure * Convert examples to esm to help promote that pattern with users * Make Promises APIs more prominent to help promite that pattern * Separate callback/sync apis into distinct sections to make those more consistent with the Promises api * Improve other bits and pieces Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/37170 Backport-PR-URL: https://github.com/nodejs/node/pull/39706 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Matteo Collina --- doc/api/dgram.md | 3 + doc/api/fs.md | 6160 ++++++++++++++++++++++++---------------------- 2 files changed, 3246 insertions(+), 2917 deletions(-) diff --git a/doc/api/dgram.md b/doc/api/dgram.md index aec685ba8ce601..1e2d46f6159ceb 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -733,6 +733,9 @@ chained. -```js -fs.open(Buffer.from('/open/some/file.txt'), 'r', (err, fd) => { - if (err) throw err; - fs.close(fd, (err) => { - if (err) throw err; - }); -}); -``` +The `fs/promises` API provides asynchronous file system methods that return +promises. -On Windows, Node.js follows the concept of per-drive working directory. This -behavior can be observed when using a drive path without a backslash. For -example `fs.readdirSync('C:\\')` can potentially return a different result than -`fs.readdirSync('C:')`. For more information, see -[this MSDN page][MSDN-Rel-Path]. +The promise APIs use the underlying Node.js threadpool to perform file +system operations off the event loop thread. These operations are not +synchronized or threadsafe. Care must be taken when performing multiple +concurrent modifications on the same file or data corruption may occur. -### URL object support +### Class: `FileHandle` -For most `fs` module functions, the `path` or `filename` argument may be passed -as a WHATWG [`URL`][] object. Only [`URL`][] objects using the `file:` protocol -are supported. -```js -const fs = require('fs'); -const fileUrl = new URL('file:///tmp/hello'); +A {FileHandle} object is an object wrapper for a numeric file descriptor. -fs.readFileSync(fileUrl); -``` +Instances of the {FileHandle} object are created by the `fsPromises.open()` +method. -`file:` URLs are always absolute paths. +All {FileHandle} objects are {EventEmitter}s. -Using WHATWG [`URL`][] objects might introduce platform-specific behaviors. +If a {FileHandle} is not closed using the `filehandle.close()` method, it will +try to automatically close the file descriptor and emit a process warning, +helping to prevent memory leaks. Please do not rely on this behavior because +it can be unreliable and the file may not be closed. Instead, always explicitly +close {FileHandle}s. Node.js may change this behavior in the future. -On Windows, `file:` URLs with a host name convert to UNC paths, while `file:` -URLs with drive letters convert to local absolute paths. `file:` URLs without a -host name nor a drive letter will result in a throw: +#### `filehandle.appendFile(data[, options])` + -```js -// On Windows : +* `data` {string|Buffer|TypedArray|DataView} +* `options` {Object|string} + * `encoding` {string|null} **Default:** `'utf8'` +* Returns: {Promise} Fulfills with `undefined` upon success. -// - WHATWG file URLs with hostname convert to UNC path -// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file -fs.readFileSync(new URL('file://hostname/p/a/t/h/file')); +Alias of [`filehandle.writeFile()`][]. -// - WHATWG file URLs with drive letters convert to absolute path -// file:///C:/tmp/hello => C:\tmp\hello -fs.readFileSync(new URL('file:///C:/tmp/hello')); +When operating on file handles, the mode cannot be changed from what it was set +to with [`fsPromises.open()`][]. Therefore, this is equivalent to +[`filehandle.writeFile()`][]. -// - WHATWG file URLs without hostname must have a drive letters -fs.readFileSync(new URL('file:///notdriveletter/p/a/t/h/file')); -fs.readFileSync(new URL('file:///c/p/a/t/h/file')); -// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute -``` +#### `filehandle.chmod(mode)` + -`file:` URLs with drive letters must use `:` as a separator just after -the drive letter. Using another separator will result in a throw. +* `mode` {integer} the file mode bit mask. +* Returns: {Promise} Fulfills with `undefined` upon success. -On all other platforms, `file:` URLs with a host name are unsupported and will -result in a throw: +Modifies the permissions on the file. See chmod(2). -```js -// On other platforms: +#### `filehandle.chown(uid, gid)` + -// - WHATWG file URLs with hostname are unsupported -// file://hostname/p/a/t/h/file => throw! -fs.readFileSync(new URL('file://hostname/p/a/t/h/file')); -// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute +* `uid` {integer} The file's new owner's user id. +* `gid` {integer} The file's new group's group id. +* Returns: {Promise} Fulfills with `undefined` upon success. -// - WHATWG file URLs convert to absolute path -// file:///tmp/hello => /tmp/hello -fs.readFileSync(new URL('file:///tmp/hello')); -``` +Changes the ownership of the file. A wrapper for chown(2). -A `file:` URL having encoded slash characters will result in a throw on all -platforms: +#### `filehandle.close()` + -```js -// On Windows -fs.readFileSync(new URL('file:///C:/p/a/t/h/%2F')); -fs.readFileSync(new URL('file:///C:/p/a/t/h/%2f')); -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded -\ or / characters */ +* Returns: {Promise} Fulfills with `undefined` upon success. -// On POSIX -fs.readFileSync(new URL('file:///p/a/t/h/%2F')); -fs.readFileSync(new URL('file:///p/a/t/h/%2f')); -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded -/ characters */ -``` +Closes the file handle after waiting for any pending operation on the handle to +complete. -On Windows, `file:` URLs having encoded backslash will result in a throw: +```js esm +import { open } from 'fs/promises'; -```js -// On Windows -fs.readFileSync(new URL('file:///C:/path/%5C')); -fs.readFileSync(new URL('file:///C:/path/%5c')); -/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded -\ or / characters */ +let filehandle; +try { + filehandle = await open('thefile.txt', 'r'); +} finally { + await filehandle?.close(); +} ``` -## File descriptors - -On POSIX systems, for every process, the kernel maintains a table of currently -open files and resources. Each open file is assigned a simple numeric -identifier called a *file descriptor*. At the system-level, all file system -operations use these file descriptors to identify and track each specific -file. Windows systems use a different but conceptually similar mechanism for -tracking resources. To simplify things for users, Node.js abstracts away the -specific differences between operating systems and assigns all open files a -numeric file descriptor. - -The `fs.open()` method is used to allocate a new file descriptor. Once -allocated, the file descriptor may be used to read data from, write data to, -or request information about the file. - -```js -fs.open('/open/some/file.txt', 'r', (err, fd) => { - if (err) throw err; - fs.fstat(fd, (err, stat) => { - if (err) throw err; - // use stat - - // always close the file descriptor! - fs.close(fd, (err) => { - if (err) throw err; - }); - }); -}); -``` +#### `filehandle.datasync()` + -Most operating systems limit the number of file descriptors that may be open -at any given time so it is critical to close the descriptor when operations -are completed. Failure to do so will result in a memory leak that will -eventually cause an application to crash. +* Returns: {Promise} Fulfills with `undefined` upon success. -## Threadpool usage +Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details. -All file system APIs except `fs.FSWatcher()` and those that are explicitly -synchronous use libuv's threadpool, which can have surprising and negative -performance implications for some applications. See the -[`UV_THREADPOOL_SIZE`][] documentation for more information. +Unlike `filehandle.sync` this method does not flush modified metadata. -## Class: `fs.Dir` +#### `filehandle.fd` -A class representing a directory stream. - -Created by [`fs.opendir()`][], [`fs.opendirSync()`][], or -[`fsPromises.opendir()`][]. - -```js -const fs = require('fs'); - -async function print(path) { - const dir = await fs.promises.opendir(path); - for await (const dirent of dir) { - console.log(dirent.name); - } -} -print('./').catch(console.error); -``` +* {number} The numeric file descriptor managed by the {FileHandle} object. -### `dir.close()` +#### `filehandle.read(buffer, offset, length, position)` -* Returns: {Promise} +* `buffer` {Buffer|Uint8Array} A buffer that will be filled with the file + data read. +* `offset` {integer} The location in the buffer at which to start filling. + **Default:** `0` +* `length` {integer} The number of bytes to read. **Default:** `buffer.length` +* `position` {integer} The location where to begin reading data from the + file. If `null`, data will be read from the current file position, and + the position will be updated. If `position` is an integer, the current + file position will remain unchanged. +* Returns: {Promise} Fulfills upon success with an object with two properties: + * `bytesRead` {integer} The number of bytes read + * `buffer` {Buffer|Uint8Array} A reference to the passed in `buffer` argument. -Asynchronously close the directory's underlying resource handle. -Subsequent reads will result in errors. +Reads data from the file and stores that in the given buffer. -A `Promise` is returned that will be fulfilled after the resource has been -closed. +If the file is not modified concurrently, the end-of-file is reached when the +number of bytes read is zero. -### `dir.close(callback)` +#### `filehandle.read(options)` +* `options` {Object} + * `buffer` {Buffer|Uint8Array} A buffer that will be filled with the file + data read. **Default:** `Buffer.alloc(16384)` + * `offset` {integer} The location in the buffer at which to start filling. + **Default:** `0` + * `length` {integer} The number of bytes to read. **Default:** `buffer.length` + * `position` {integer} The location where to begin reading data from the + file. If `null`, data will be read from the current file position, and + the position will be updated. If `position` is an integer, the current + file position will remain unchanged. **Default:**: `null` +* Returns: {Promise} Fulfills upon success with an object with two properties: + * `bytesRead` {integer} The number of bytes read + * `buffer` {Buffer|Uint8Array} A reference to the passed in `buffer` + argument. + +Reads data from the file and stores that in the given buffer. -* `callback` {Function} - * `err` {Error} - -Asynchronously close the directory's underlying resource handle. -Subsequent reads will result in errors. - -The `callback` will be called after the resource handle has been closed. +If the file is not modified concurrently, the end-of-file is reached when the +number of bytes read is zero. -### `dir.closeSync()` +#### `filehandle.readFile(options)` -Synchronously close the directory's underlying resource handle. -Subsequent reads will result in errors. +* `options` {Object|string} + * `encoding` {string|null} **Default:** `null` + * `signal` {AbortSignal} allows aborting an in-progress readFile +* Returns: {Promise} Fulfills upon a successful read with the contents of the + file. If no encoding is specified (using `options.encoding`), the data is + returned as a {Buffer} object. Otherwise, the data will be a string. -### `dir.path` - +Asynchronously reads the entire contents of a file. -* {string} +If `options` is a string, then it specifies the `encoding`. -The read-only path of this directory as was provided to [`fs.opendir()`][], -[`fs.opendirSync()`][], or [`fsPromises.opendir()`][]. +The {FileHandle} has to support reading. + +If one or more `filehandle.read()` calls are made on a file handle and then a +`filehandle.readFile()` call is made, the data will be read from the current +position till the end of the file. It doesn't always read from the beginning +of the file. -### `dir.read()` +#### `filehandle.readv(buffers[, position])` -* Returns: {Promise} containing {fs.Dirent|null} - -Asynchronously read the next directory entry via readdir(3) as an -[`fs.Dirent`][]. - -After the read is completed, a `Promise` is returned that will be fulfilled -with an [`fs.Dirent`][], or `null` if there are no more directory entries to -read. +* `buffers` {Buffer[]|TypedArray[]|DataView[]} +* `position` {integer} The offset from the beginning of the file where the data + should be read from. If `position` is not a `number`, the data will be read + from the current position. +* Returns: {Promise} Fulfills upon success an object containing two properties: + * `bytesRead` {integer} the number of bytes read + * `buffers` {Buffer[]|TypedArray[]|DataView[]} property containing + a reference to the `buffers` input. -Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory might not be -included in the iteration results. +Read from a file and write to an array of {ArrayBufferView}s -### `dir.read(callback)` +#### `filehandle.stat([options])` -* `callback` {Function} - * `err` {Error} - * `dirent` {fs.Dirent|null} - -Asynchronously read the next directory entry via readdir(3) as an -[`fs.Dirent`][]. - -After the read is completed, the `callback` will be called with an -[`fs.Dirent`][], or `null` if there are no more directory entries to read. - -Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory might not be -included in the iteration results. +* `options` {Object} + * `bigint` {boolean} Whether the numeric values in the returned + {fs.Stats} object should be `bigint`. **Default:** `false`. +* Returns: {Promise} Fulfills with an {fs.Stats} for the file. -### `dir.readSync()` +#### `filehandle.sync()` -* Returns: {fs.Dirent|null} - -Synchronously read the next directory entry via readdir(3) as an -[`fs.Dirent`][]. +* Returns: {Promise} Fufills with `undefined` upon success. -If there are no more directory entries to read, `null` will be returned. - -Directory entries returned by this function are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory might not be -included in the iteration results. +Request that all data for the open file descriptor is flushed to the storage +device. The specific implementation is operating system and device specific. +Refer to the POSIX fsync(2) documentation for more detail. -### `dir[Symbol.asyncIterator]()` +#### `filehandle.truncate(len)` -* Returns: {AsyncIterator} of {fs.Dirent} - -Asynchronously iterates over the directory via readdir(3) until all entries have -been read. +* `len` {integer} **Default:** `0` +* Returns: {Promise} Fulfills with `undefined` upo nsuccess. -Entries returned by the async iterator are always an [`fs.Dirent`][]. -The `null` case from `dir.read()` is handled internally. +Truncates the file. -See [`fs.Dir`][] for an example. +If the file was larger than `len` bytes, only the first `len` bytes will be +retained in the file. -Directory entries returned by this iterator are in no particular order as -provided by the operating system's underlying directory mechanisms. -Entries added or removed while iterating over the directory might not be -included in the iteration results. +The following example retains only the first four bytes of the file: -## Class: `fs.Dirent` - +```js esm +import { open } from 'fs/promises'; -A representation of a directory entry, which can be a file or a subdirectory -within the directory, as returned by reading from an [`fs.Dir`][]. The -directory entry is a combination of the file name and file type pairs. +let filehandle = null; +try { + filehandle = await open('temp.txt', 'r+'); + await filehandle.truncate(4); +} finally { + filehandle?.close(); +} +``` -Additionally, when [`fs.readdir()`][] or [`fs.readdirSync()`][] is called with -the `withFileTypes` option set to `true`, the resulting array is filled with -`fs.Dirent` objects, rather than strings or `Buffers`. +If the file previously was shorter than `len` bytes, it is extended, and the +extended part is filled with null bytes (`'\0'`): -### `dirent.isBlockDevice()` +#### `filehandle.utimes(atime, mtime)` -* Returns: {boolean} +* `atime` {number|string|Date} +* `mtime` {number|string|Date} +* Returns: {Promise} + +Change the file system timestamps of the object referenced by the {FileHandle} +then resolves the promise with no arguments upon success. -Returns `true` if the `fs.Dirent` object describes a block device. +This function does not work on AIX versions before 7.1, it will reject the +promise with an error using code `UV_ENOSYS`. -### `dirent.isCharacterDevice()` +#### `filehandle.write(buffer[, offset[, length[, position]]])` -* Returns: {boolean} +* `buffer` {Buffer|Uint8Array|string|Object} +* `offset` {integer} The start position from within `buffer` where the data + to write begins. +* `length` {integer} The number of bytes from `buffer` to write. +* `position` {integer} The offset from the beginning of the file where the + data from `buffer` should be written. If `position` is not a `number`, + the data will be written at the current position. See the POSIX pwrite(2) + documentation for more detail. +* Returns: {Promise} -Returns `true` if the `fs.Dirent` object describes a character device. +Write `buffer` to the file. -### `dirent.isDirectory()` - +The promise is resolved with an object containing two properties: -* Returns: {boolean} +* `bytesWritten` {integer} the number of bytes written +* `buffer` {Buffer|Uint8Array|string|Object} a reference to the `buffer` + written. -Returns `true` if the `fs.Dirent` object describes a file system -directory. +It is unsafe to use `filehandle.write()` multiple times on the same file +without waiting for the promise to be resolved (or rejected). For this +scenario, use [`fs.createWriteStream()`][]. -### `dirent.isFIFO()` +On Linux, positional writes do not work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file. + +#### `filehandle.write(string[, position[, encoding]])` -* Returns: {boolean} +* `string` {string|Object} +* `position` {integer} The offset from the beginning of the file where the + data from `string` should be written. If `position` is not a `number` the + data will be written at the current position. See the POSIX pwrite(2) + documentation for more detail. +* `encoding` {string} The expected string encoding. **Default:** `'utf8'` +* Returns: {Promise} -Returns `true` if the `fs.Dirent` object describes a first-in-first-out -(FIFO) pipe. +Write `string` to the file. If `string` is not a string, or an object with an +own `toString` function property, the promise is rejected with an error. -### `dirent.isFile()` - +The promise is resolved with an object containing two properties: -* Returns: {boolean} +* `bytesWritten` {integer} the number of bytes written +* `buffer` {string|Object} a reference to the `string` written. -Returns `true` if the `fs.Dirent` object describes a regular file. +It is unsafe to use `filehandle.write()` multiple times on the same file +without waiting for the promise to be resolved (or rejected). For this +scenario, use [`fs.createWriteStream()`][]. + +On Linux, positional writes do not work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file. -### `dirent.isSocket()` +#### `filehandle.writeFile(data, options)` -* Returns: {boolean} +* `data` {string|Buffer|Uint8Array|Object} +* `options` {Object|string} + * `encoding` {string|null} The expected character encoding when `data` is a + string. **Default:** `'utf8'` +* Returns: {Promise} + +Asynchronously writes data to a file, replacing the file if it already exists. +`data` can be a string, a buffer, or an object with an own `toString` function +property. The promise is resolved with no arguments upon success. -Returns `true` if the `fs.Dirent` object describes a socket. +If `options` is a string, then it specifies the `encoding`. -### `dirent.isSymbolicLink()` - +The {FileHandle} has to support writing. -* Returns: {boolean} +It is unsafe to use `filehandle.writeFile()` multiple times on the same file +without waiting for the promise to be resolved (or rejected). -Returns `true` if the `fs.Dirent` object describes a symbolic link. +If one or more `filehandle.write()` calls are made on a file handle and then a +`filehandle.writeFile()` call is made, the data will be written from the +current position till the end of the file. It doesn't always write from the +beginning of the file. -### `dirent.name` +#### `filehandle.writev(buffers[, position])` -* {string|Buffer} +* `buffers` {Buffer[]|TypedArray[]|DataView[]} +* `position` {integer} The offset from the beginning of the file where the + data from `buffers` should be written. If `position` is not a `number`, + the data will be written at the current position. +* Returns: {Promise} -The file name that this `fs.Dirent` object refers to. The type of this -value is determined by the `options.encoding` passed to [`fs.readdir()`][] or -[`fs.readdirSync()`][]. +Write an array of {ArrayBufferView}s to the file. -## Class: `fs.FSWatcher` - +The promise is resolved with an object containing a two properties: -* Extends {EventEmitter} +* `bytesWritten` {integer} the number of bytes written +* `buffers` {Buffer[]|TypedArray[]|DataView[]} a reference to the `buffers` + input. -A successful call to [`fs.watch()`][] method will return a new `fs.FSWatcher` -object. +It is unsafe to call `writev()` multiple times on the same file without waiting +for the promise to be resolved (or rejected). -All `fs.FSWatcher` objects emit a `'change'` event whenever a specific watched -file is modified. +On Linux, positional writes don't work when the file is opened in append mode. +The kernel ignores the position argument and always appends the data to +the end of the file. -### Event: `'change'` +### `fsPromises.access(path[, mode])` -* `eventType` {string} The type of change event that has occurred -* `filename` {string|Buffer} The filename that changed (if relevant/available) +* `path` {string|Buffer|URL} +* `mode` {integer} **Default:** `fs.constants.F_OK` +* Returns: {Promise} Fulfills with `undefined` upon success. -Emitted when something changes in a watched directory or file. -See more details in [`fs.watch()`][]. +Tests a user's permissions for the file or directory specified by `path`. +The `mode` argument is an optional integer that specifies the accessibility +checks to be performed. Check [File access constants][] for possible values +of `mode`. It is possible to create a mask consisting of the bitwise OR of +two or more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`). -The `filename` argument may not be provided depending on operating system -support. If `filename` is provided, it will be provided as a `Buffer` if -`fs.watch()` is called with its `encoding` option set to `'buffer'`, otherwise -`filename` will be a UTF-8 string. +If the accessibility check is successful, the promise is resolved with no +value. If any of the accessibility checks fail, the promise is rejected +with an {Error} object. The following example checks if the file +`/etc/passwd` can be read and written by the current process. -```js -// Example when handled through fs.watch() listener -fs.watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => { - if (filename) { - console.log(filename); - // Prints: - } -}); +```js esm +import { access } from 'fs/promises'; +import { constants } from 'fs'; + +try { + await access('/etc/passwd', constants.R_OK | constants.W_OK); + console.log('can access'); +} catch { + console.error('cannot access'); +} ``` -### Event: `'close'` +Using `fsPromises.access()` to check for the accessibility of a file before +calling `fsPromises.open()` is not recommended. Doing so introduces a race +condition, since other processes may change the file's state between the two +calls. Instead, user code should open/read/write the file directly and handle +the error raised if the file is not accessible. + +### `fsPromises.appendFile(path, data[, options])` -Emitted when the watcher stops watching for changes. The closed -`fs.FSWatcher` object is no longer usable in the event handler. +* `path` {string|Buffer|URL|FileHandle} filename or {FileHandle} +* `data` {string|Buffer} +* `options` {Object|string} + * `encoding` {string|null} **Default:** `'utf8'` + * `mode` {integer} **Default:** `0o666` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`. +* Returns: {Promise} Fulfills with `undefined` upon success. -### Event: `'error'` - +Asynchronously append data to a file, creating the file if it does not yet +exist. `data` can be a string or a {Buffer}. -* `error` {Error} +If `options` is a string, then it specifies the `encoding`. -Emitted when an error occurs while watching the file. The errored -`fs.FSWatcher` object is no longer usable in the event handler. +The `path` may be specified as a {FileHandle} that has been opened +for appending (using `fsPromises.open()`). -### `watcher.close()` +### `fsPromises.chmod(path, mode)` -Stop watching for changes on the given `fs.FSWatcher`. Once stopped, the -`fs.FSWatcher` object is no longer usable. +* `path` {string|Buffer|URL} +* `mode` {string|integer} +* Returns: {Promise} Fulfills with `undefined` upon success. -### `watcher.ref()` +Changes the permissions of a file. + +### `fsPromises.chown(path, uid, gid)` -* Returns: {fs.FSWatcher} - -When called, requests that the Node.js event loop *not* exit so long as the -`FSWatcher` is active. Calling `watcher.ref()` multiple times will have -no effect. +* `path` {string|Buffer|URL} +* `uid` {integer} +* `gid` {integer} +* Returns: {Promise} Fulfills with `undefined` upon success. -By default, all `FSWatcher` objects are "ref'ed", making it normally -unnecessary to call `watcher.ref()` unless `watcher.unref()` had been -called previously. +Changes the ownership of a file. -### `watcher.unref()` +### `fsPromises.copyFile(src, dest[, mode])` -* Returns: {fs.FSWatcher} +* `src` {string|Buffer|URL} source filename to copy +* `dest` {string|Buffer|URL} destination filename of the copy operation +* `mode` {integer} Optional modifiers that specify the behavior of the copy + operation. It is possible to create a mask consisting of the bitwise OR of + two or more values (e.g. + `fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`) + **Default:** `0`. + * `fs.constants.COPYFILE_EXCL`: The copy operation will fail if `dest` + already exists. + * `fs.constants.COPYFILE_FICLONE`: The copy operation will attempt to create + a copy-on-write reflink. If the platform does not support copy-on-write, + then a fallback copy mechanism is used. + * `fs.constants.COPYFILE_FICLONE_FORCE`: The copy operation will attempt to + create a copy-on-write reflink. If the platform does not support + copy-on-write, then the operation will fail. +* Returns: {Promise} Fulfills with `undefined` upon success. -When called, the active `FSWatcher` object will not require the Node.js -event loop to remain active. If there is no other activity keeping the -event loop running, the process may exit before the `FSWatcher` object's -callback is invoked. Calling `watcher.unref()` multiple times will have -no effect. +Asynchronously copies `src` to `dest`. By default, `dest` is overwritten if it +already exists. -## Class: `fs.StatWatcher` - +No guarantees are made about the atomicity of the copy operation. If an +error occurs after the destination file has been opened for writing, an attempt +will be made to remove the destination. -* Extends {EventEmitter} +```js esm +import { constants } from 'fs'; +import { copyFile } from 'fs/promises'; -A successful call to `fs.watchFile()` method will return a new `fs.StatWatcher` -object. +try { + await copyFile('source.txt', 'destination.txt'); + console.log('source.txt was copied to destination.txt'); +} catch { + console.log('The file could not be copied'); +} + +// By using COPYFILE_EXCL, the operation will fail if destination.txt exists. +try { + await copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL); + console.log('source.txt was copied to destination.txt'); +} catch { + console.log('The file could not be copied'); +} +``` -### `watcher.ref()` +### `fsPromises.lchmod(path, mode)` -* Returns: {fs.StatWatcher} +* `path` {string|Buffer|URL} +* `mode` {integer} +* Returns: {Promise} Fulfills with `undefined` upon success. -When called, requests that the Node.js event loop *not* exit so long as the -`StatWatcher` is active. Calling `watcher.ref()` multiple times will have -no effect. +Changes the permissions on a symbolic link. -By default, all `StatWatcher` objects are "ref'ed", making it normally -unnecessary to call `watcher.ref()` unless `watcher.unref()` had been -called previously. +This method is only implemented on macOS. -### `watcher.unref()` +### `fsPromises.lchown(path, uid, gid)` -* Returns: {fs.StatWatcher} +* `path` {string|Buffer|URL} +* `uid` {integer} +* `gid` {integer} +* Returns: {Promise} Fulfills with `undefined` upon success. -When called, the active `StatWatcher` object will not require the Node.js -event loop to remain active. If there is no other activity keeping the -event loop running, the process may exit before the `StatWatcher` object's -callback is invoked. Calling `watcher.unref()` multiple times will have -no effect. +Changes the ownership on a symbolic link. -## Class: `fs.ReadStream` +### `fsPromises.lutimes(path, atime, mtime)` -* Extends: {stream.Readable} +* `path` {string|Buffer|URL} +* `atime` {number|string|Date} +* `mtime` {number|string|Date} +* Returns: {Promise} Fulfills with `undefined` upon success. -Instances of `fs.ReadStream` are created and returned using the -[`fs.createReadStream()`][] function. +Changes the access and modification times of a file in the same way as +[`fsPromises.utimes()`][], with the difference that if the path refers to a +symbolic link, then the link is not dereferenced: instead, the timestamps of +the symbolic link itself are changed. -### Event: `'close'` +### `fsPromises.link(existingPath, newPath)` -Emitted when the `fs.ReadStream`'s underlying file descriptor has been closed. +* `existingPath` {string|Buffer|URL} +* `newPath` {string|Buffer|URL} +* Returns: {Promise} Fulfills with `undefined` upon success. -### Event: `'open'` +Creates a new link from the `existingPath` to the `newPath`. See the POSIX +link(2) documentation for more detail. + +### `fsPromises.lstat(path[, options])` -* `fd` {integer} Integer file descriptor used by the `ReadStream`. +* `path` {string|Buffer|URL} +* `options` {Object} + * `bigint` {boolean} Whether the numeric values in the returned + {fs.Stats} object should be `bigint`. **Default:** `false`. +* Returns: {Promise} Fulfills with the {fs.Stats} object for the given + symbolic link `path`. -Emitted when the `fs.ReadStream`'s file descriptor has been opened. +Equivalent to `fsPromises.stats()` when `path` refers to a symbolic link. +Refer to the POSIX lstat(2) document for more detail. -### Event: `'ready'` +### `fsPromises.mkdir(path[, options])` -Emitted when the `fs.ReadStream` is ready to be used. +* `path` {string|Buffer|URL} +* `options` {Object|integer} + * `recursive` {boolean} **Default:** `false` + * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. +* Returns: {Promise} Upon success, fulfills with `undefined` if `recursive` + is `false`, or the first directory path created if `recursive` is `true`. + +Asynchronously creates a directory. -Fires immediately after `'open'`. +The optional `options` argument can be an integer specifying `mode` (permission +and sticky bits), or an object with a `mode` property and a `recursive` +property indicating whether parent directories should be created. Calling +`fsPromises.mkdir()` when `path` is a directory that exists results in a +rejection only when `recursive` is false. -### `readStream.bytesRead` +### `fsPromises.mkdtemp(prefix[, options])` -* {number} +* `prefix` {string} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {Promise} Fulfills with a string containing the filesystem path + of the newly created temporary directory. -The number of bytes that have been read so far. +Creates a unique temporary directory. A unique directory name is generated by +appending six random characters to the end of the provided `prefix`. Due to +platform inconsistencies, avoid trailing `X` characters in `prefix`. Some +platforms, notably the BSDs, can return more than six random characters, and +replace trailing `X` characters in `prefix` with random characters. -### `readStream.path` - +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use. -* {string|Buffer} +```js esm +import { mkdtemp } from 'fs/promises'; -The path to the file the stream is reading from as specified in the first -argument to `fs.createReadStream()`. If `path` is passed as a string, then -`readStream.path` will be a string. If `path` is passed as a `Buffer`, then -`readStream.path` will be a `Buffer`. +try { + await mkdtemp(path.join(os.tmpdir(), 'foo-')); +} catch (err) { + console.error(err); +} +``` + +The `fsPromises.mkdtemp()` method will append the six randomly selected +characters directly to the `prefix` string. For instance, given a directory +`/tmp`, if the intention is to create a temporary directory *within* `/tmp`, the +`prefix` must end with a trailing platform-specific path separator +(`require('path').sep`). -### `readStream.pending` +### `fsPromises.open(path, flags[, mode])` -* {boolean} +* `path` {string|Buffer|URL} +* `flags` {string|number} See [support of file system `flags`][]. + **Default:** `'r'`. +* `mode` {string|integer} Sets the file mode (permission and sticky bits) + if the file is created. **Default:** `0o666` (readable and writable) +* Returns: {Promise} Fullfils with a {FileHandle} object. -This property is `true` if the underlying file has not been opened yet, -i.e. before the `'ready'` event is emitted. +Opens a {FileHandle}. + +Refer to the POSIX open(2) documentation for more detail. + +Some characters (`< > : " / \ | ? *`) are reserved under Windows as documented +by [Naming Files, Paths, and Namespaces][]. Under NTFS, if the filename contains +a colon, Node.js will open a file system stream, as described by +[this MSDN page][MSDN-Using-Streams]. -## Class: `fs.Stats` +### `fsPromises.opendir(path[, options])` -A `fs.Stats` object provides information about a file. - -Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and -their synchronous counterparts are of this type. -If `bigint` in the `options` passed to those methods is true, the numeric values -will be `bigint` instead of `number`, and the object will contain additional -nanosecond-precision properties suffixed with `Ns`. +* `path` {string|Buffer|URL} +* `options` {Object} + * `encoding` {string|null} **Default:** `'utf8'` + * `bufferSize` {number} Number of directory entries that are buffered + internally when reading from the directory. Higher values lead to better + performance but higher memory usage. **Default:** `32` +* Returns: {Promise} Fulfills with an {fs.Dir}. -```console -Stats { - dev: 2114, - ino: 48064969, - mode: 33188, - nlink: 1, - uid: 85, - gid: 100, - rdev: 0, - size: 527, - blksize: 4096, - blocks: 8, - atimeMs: 1318289051000.1, - mtimeMs: 1318289051000.1, - ctimeMs: 1318289051000.1, - birthtimeMs: 1318289051000.1, - atime: Mon, 10 Oct 2011 23:24:11 GMT, - mtime: Mon, 10 Oct 2011 23:24:11 GMT, - ctime: Mon, 10 Oct 2011 23:24:11 GMT, - birthtime: Mon, 10 Oct 2011 23:24:11 GMT } -``` +Asynchronously open a directory for iterative scanning. See the POSIX +opendir(3) documentation for more detail. -`bigint` version: +Creates an {fs.Dir}, which contains all further functions for reading from +and cleaning up the directory. -```console -BigIntStats { - dev: 2114n, - ino: 48064969n, - mode: 33188n, - nlink: 1n, - uid: 85n, - gid: 100n, - rdev: 0n, - size: 527n, - blksize: 4096n, - blocks: 8n, - atimeMs: 1318289051000n, - mtimeMs: 1318289051000n, - ctimeMs: 1318289051000n, - birthtimeMs: 1318289051000n, - atimeNs: 1318289051000000000n, - mtimeNs: 1318289051000000000n, - ctimeNs: 1318289051000000000n, - birthtimeNs: 1318289051000000000n, - atime: Mon, 10 Oct 2011 23:24:11 GMT, - mtime: Mon, 10 Oct 2011 23:24:11 GMT, - ctime: Mon, 10 Oct 2011 23:24:11 GMT, - birthtime: Mon, 10 Oct 2011 23:24:11 GMT } -``` +The `encoding` option sets the encoding for the `path` while opening the +directory and subsequent read operations. -### `stats.isBlockDevice()` - +Example using async iteration: -* Returns: {boolean} +```js esm +import { opendir } from 'fs/promises'; -Returns `true` if the `fs.Stats` object describes a block device. +try { + const dir = await opendir('./'); + for await (const dirent of dir) + console.log(dirent.name); +} catch (err) { + console.error(err); +} +``` -### `stats.isCharacterDevice()` +### `fsPromises.readdir(path[, options])` -* Returns: {boolean} +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` + * `withFileTypes` {boolean} **Default:** `false` +* Returns: {Promise} Fulfills with an array of the names of the files in + the directory excluding `'.'` and `'..'`. -Returns `true` if the `fs.Stats` object describes a character device. +Reads the contents of a directory. -### `stats.isDirectory()` - +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the filenames. If the `encoding` is set to `'buffer'`, the filenames returned +will be passed as {Buffer} objects. -* Returns: {boolean} +If `options.withFileTypes` is set to `true`, the resolved array will contain +{fs.Dirent} objects. -Returns `true` if the `fs.Stats` object describes a file system directory. +```js esm +import { readdir } from 'fs/promises'; -If the `fs.Stats` object was obtained from [`fs.lstat()`][], this method will -always return `false`. This is because [`fs.lstat()`][] returns information -about a symbolic link itself and not the path it resolves to. - -### `stats.isFIFO()` - - -* Returns: {boolean} - -Returns `true` if the `fs.Stats` object describes a first-in-first-out (FIFO) -pipe. - -### `stats.isFile()` - - -* Returns: {boolean} - -Returns `true` if the `fs.Stats` object describes a regular file. - -### `stats.isSocket()` - - -* Returns: {boolean} - -Returns `true` if the `fs.Stats` object describes a socket. +try { + const files = await readdir(path); + for await (const file of files) + console.log(file); +} catch (err) { + console.error(err); +} +``` -### `stats.isSymbolicLink()` +### `fsPromises.readFile(path[, options])` -* Returns: {boolean} - -Returns `true` if the `fs.Stats` object describes a symbolic link. - -This method is only valid when using [`fs.lstat()`][]. - -### `stats.dev` - -* {number|bigint} - -The numeric identifier of the device containing the file. - -### `stats.ino` - -* {number|bigint} - -The file system specific "Inode" number for the file. - -### `stats.mode` - -* {number|bigint} - -A bit-field describing the file type and mode. - -### `stats.nlink` +* `path` {string|Buffer|URL|FileHandle} filename or `FileHandle` +* `options` {Object|string} + * `encoding` {string|null} **Default:** `null` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'r'`. + * `signal` {AbortSignal} allows aborting an in-progress readFile +* Returns: {Promise} Fulfills with the contents of the file. -* {number|bigint} +Asynchronously reads the entire contents of a file. -The number of hard-links that exist for the file. +If no encoding is specified (using `options.encoding`), the data is returned +as a {Buffer} object. Otherwise, the data will be a string. -### `stats.uid` +If `options` is a string, then it specifies the encoding. -* {number|bigint} +When the `path` is a directory, the behavior of `fsPromises.readFile()` is +platform-specific. On macOS, Linux, and Windows, the promise will be rejected +with an error. On FreeBSD, a representation of the directory's contents will be +returned. -The numeric user identifier of the user that owns the file (POSIX). +It is possible to abort an ongoing `readFile` using an {AbortSignal}. If a +request is aborted the promise returned is rejected with an `AbortError`: -### `stats.gid` +```js esm +import { readFile } from 'fs/promises'; -* {number|bigint} +try { + const controller = new AbortController(); + const signal = controller.signal; + readFile(fileName, { signal }); -The numeric group identifier of the group that owns the file (POSIX). + // Abort the request + controller.abort(); +} catch (err) { + console.error(err); +} +``` -### `stats.rdev` +Aborting an ongoing request does not abort individual operating +system requests but rather the internal buffering `fs.readFile` performs. -* {number|bigint} +Any specified {FileHandle} has to support reading. -A numeric device identifier if the file represents a device. +### `fsPromises.readlink(path[, options])` + -### `stats.size` +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {Promise} Fulfills with the `linkString` upon success. -* {number|bigint} +Reads the contents of the symbolic link refered to by `path`. See the POSIX +readlink(2) documentation for more etail. The promise is resolved with the +`linkString` upon success. -The size of the file in bytes. +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the link path returned. If the `encoding` is set to `'buffer'`, the link path +returned will be passed as a {Buffer} object. -### `stats.blksize` +### `fsPromises.realpath(path[, options])` + -* {number|bigint} +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {Promise} Fulfills with the resolved path upon success. -The file system block size for i/o operations. +Determines the actual location of `path` using the same semantics as the +`fs.realpath.native()` function. -### `stats.blocks` +Only paths that can be converted to UTF8 strings are supported. -* {number|bigint} +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the path. If the `encoding` is set to `'buffer'`, the path returned will be +passed as a {Buffer} object. -The number of blocks allocated for this file. +On Linux, when Node.js is linked against musl libc, the procfs file system must +be mounted on `/proc` in order for this function to work. Glibc does not have +this restriction. -### `stats.atimeMs` +### `fsPromises.rename(oldPath, newPath)` -* {number|bigint} +* `oldPath` {string|Buffer|URL} +* `newPath` {string|Buffer|URL} +* Returns: {Promise} Fulfills with `undefined` upon success. -The timestamp indicating the last time this file was accessed expressed in -milliseconds since the POSIX Epoch. +Renames `oldPath` to `newPath`. -### `stats.mtimeMs` +### `fsPromises.rmdir(path[, options])` -* {number|bigint} - -The timestamp indicating the last time this file was modified expressed in -milliseconds since the POSIX Epoch. +* `path` {string|Buffer|URL} +* `options` {Object} + * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or + `EPERM` error is encountered, Node.js retries the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. + * `recursive` {boolean} If `true`, perform a recursive directory removal. In + recursive mode, errors are not reported if `path` does not exist, and + operations are retried on failure. **Default:** `false`. + * `retryDelay` {integer} The amount of time in milliseconds to wait between + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. +* Returns: {Promise} Fulfills with `undefined` upon success. -### `stats.ctimeMs` - +Removes the directory identified by `path`. -* {number|bigint} +Using `fsPromises.rmdir()` on a file (not a directory) results in the +promise being rejected with an `ENOENT` error on Windows and an `ENOTDIR` +error on POSIX. -The timestamp indicating the last time the file status was changed expressed -in milliseconds since the POSIX Epoch. +Setting `recursive` to `true` results in behavior similar to the Unix command +`rm -rf`: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in +the future. -### `stats.birthtimeMs` +### `fsPromises.rm(path[, options])` -* {number|bigint} +* `path` {string|Buffer|URL} +* `options` {Object} + * `force` {boolean} When `true`, exceptions will be ignored if `path` does + not exist. **Default:** `false`. + * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or + `EPERM` error is encountered, Node.js will retry the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. + * `recursive` {boolean} If `true`, perform a recursive directory removal. In + recursive mode operations are retried on failure. **Default:** `false`. + * `retryDelay` {integer} The amount of time in milliseconds to wait between + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. +* Returns: {Promise} Fulfills with `undefined` upon success. -The timestamp indicating the creation time of this file expressed in -milliseconds since the POSIX Epoch. +Removes files and directories (modeled on the standard POSIX `rm` utility). -### `stats.atimeNs` +### `fsPromises.stat(path[, options])` -* {bigint} - -Only present when `bigint: true` is passed into the method that generates -the object. -The timestamp indicating the last time this file was accessed expressed in -nanoseconds since the POSIX Epoch. +* `path` {string|Buffer|URL} +* `options` {Object} + * `bigint` {boolean} Whether the numeric values in the returned + {fs.Stats} object should be `bigint`. **Default:** `false`. +* Returns: {Promise} Fulfills with the {fs.Stats} object for the + given `path`. -### `stats.mtimeNs` +### `fsPromises.symlink(target, path[, type])` -* {bigint} - -Only present when `bigint: true` is passed into the method that generates -the object. -The timestamp indicating the last time this file was modified expressed in -nanoseconds since the POSIX Epoch. - -### `stats.ctimeNs` - +* `target` {string|Buffer|URL} +* `path` {string|Buffer|URL} +* `type` {string} **Default:** `'file'` +* Returns: {Promise} Fulfills with `undefined` upon success. -* {bigint} +Creates a symbolic link. -Only present when `bigint: true` is passed into the method that generates -the object. -The timestamp indicating the last time the file status was changed expressed -in nanoseconds since the POSIX Epoch. +The `type` argument is only used on Windows platforms and can be one of `'dir'`, +`'file'`, or `'junction'`. Windows junction points require the destination path +to be absolute. When using `'junction'`, the `target` argument will +automatically be normalized to absolute path. -### `stats.birthtimeNs` +### `fsPromises.truncate(path[, len])` -* {bigint} +* `path` {string|Buffer|URL} +* `len` {integer} **Default:** `0` +* Returns: {Promise} Fulfills with `undefined` upon success. -Only present when `bigint: true` is passed into the method that generates -the object. -The timestamp indicating the creation time of this file expressed in -nanoseconds since the POSIX Epoch. +Truncates (shortens or extends the length) of the content at `path` to `len` +bytes. -### `stats.atime` +### `fsPromises.unlink(path)` -* {Date} +* `path` {string|Buffer|URL} +* Returns: {Promise} Fulfills with `undefined` upon success. -The timestamp indicating the last time this file was accessed. +If `path` refers to a symbolic link, then the link is removed without affecting +the file or directory to which that link refers. If the `path` refers to a file +path that is not a symbolic link, the file is deleted. See the POSIX unlink(2) +documentation for more detail. -### `stats.mtime` +### `fsPromises.utimes(path, atime, mtime)` -* {Date} +* `path` {string|Buffer|URL} +* `atime` {number|string|Date} +* `mtime` {number|string|Date} +* Returns: {Promise} Fulfills with `undefined` upon success. -The timestamp indicating the last time this file was modified. +Change the file system timestamps of the object referenced by `path`. -### `stats.ctime` - - -* {Date} - -The timestamp indicating the last time the file status was changed. - -### `stats.birthtime` - - -* {Date} - -The timestamp indicating the creation time of this file. - -### Stat time values - -The `atimeMs`, `mtimeMs`, `ctimeMs`, `birthtimeMs` properties are -numeric values that hold the corresponding times in milliseconds. Their -precision is platform specific. When `bigint: true` is passed into the -method that generates the object, the properties will be [bigints][], -otherwise they will be [numbers][MDN-Number]. - -The `atimeNs`, `mtimeNs`, `ctimeNs`, `birthtimeNs` properties are -[bigints][] that hold the corresponding times in nanoseconds. They are -only present when `bigint: true` is passed into the method that generates -the object. Their precision is platform specific. - -`atime`, `mtime`, `ctime`, and `birthtime` are -[`Date`][MDN-Date] object alternate representations of the various times. The -`Date` and number values are not connected. Assigning a new number value, or -mutating the `Date` value, will not be reflected in the corresponding alternate -representation. - -The times in the stat object have the following semantics: - -* `atime` "Access Time": Time when file data last accessed. Changed - by the mknod(2), utimes(2), and read(2) system calls. -* `mtime` "Modified Time": Time when file data last modified. - Changed by the mknod(2), utimes(2), and write(2) system calls. -* `ctime` "Change Time": Time when file status was last changed - (inode data modification). Changed by the chmod(2), chown(2), - link(2), mknod(2), rename(2), unlink(2), utimes(2), - read(2), and write(2) system calls. -* `birthtime` "Birth Time": Time of file creation. Set once when the - file is created. On filesystems where birthtime is not available, - this field may instead hold either the `ctime` or - `1970-01-01T00:00Z` (ie, Unix epoch timestamp `0`). This value may be greater - than `atime` or `mtime` in this case. On Darwin and other FreeBSD variants, - also set if the `atime` is explicitly set to an earlier value than the current - `birthtime` using the utimes(2) system call. - -Prior to Node.js 0.12, the `ctime` held the `birthtime` on Windows systems. As -of 0.12, `ctime` is not "creation time", and on Unix systems, it never was. - -## Class: `fs.WriteStream` - - -* Extends {stream.Writable} +The `atime` and `mtime` arguments follow these rules: -Instances of `fs.WriteStream` are created and returned using the -[`fs.createWriteStream()`][] function. +* Values can be either numbers representing Unix epoch time, `Date`s, or a + numeric string like `'123456789.0'`. +* If the value can not be converted to a number, or is `NaN`, `Infinity` or + `-Infinity`, an `Error` will be thrown. -### Event: `'close'` +### `fsPromises.writeFile(file, data[, options])` -Emitted when the `WriteStream`'s underlying file descriptor has been closed. +* `file` {string|Buffer|URL|FileHandle} filename or `FileHandle` +* `data` {string|Buffer|Uint8Array|Object} +* `options` {Object|string} + * `encoding` {string|null} **Default:** `'utf8'` + * `mode` {integer} **Default:** `0o666` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. + * `signal` {AbortSignal} allows aborting an in-progress writeFile +* Returns: {Promise} Fulfills with `undefined` upon success. -### Event: `'open'` - +Asynchronously writes data to a file, replacing the file if it already exists. +`data` can be a string, a {Buffer}, or an object with an own `toString` function +property. -* `fd` {integer} Integer file descriptor used by the `WriteStream`. +The `encoding` option is ignored if `data` is a buffer. -Emitted when the `WriteStream`'s file is opened. +If `options` is a string, then it specifies the encoding. -### Event: `'ready'` - +Any specified {FileHandle} has to support writing. -Emitted when the `fs.WriteStream` is ready to be used. +It is unsafe to use `fsPromises.writeFile()` multiple times on the same file +without waiting for the promise to be settled. -Fires immediately after `'open'`. +Similarly to `fsPromises.readFile` - `fsPromises.writeFile` is a convenience +method that performs multiple `write` calls internally to write the buffer +passed to it. For performance sensitive code consider using +[`fs.createWriteStream()`][]. -### `writeStream.bytesWritten` - +It is possible to use an {AbortSignal} to cancel an `fsPromises.writeFile()`. +Cancelation is "best effort", and some amount of data is likely still +to be written. -The number of bytes written so far. Does not include data that is still queued -for writing. +```js esm +import { writeFile } from 'fs/promises'; -### `writeStream.path` - +try { + const controller = new AbortController(); + const { signal } = controller; + const data = new Uint8Array(Buffer.from('Hello Node.js')); + writeFile('message.txt', data, { signal }); + controller.abort(); +} catch (err) { + // When a request is aborted - err is an AbortError + console.error(err); +} +``` -The path to the file the stream is writing to as specified in the first -argument to [`fs.createWriteStream()`][]. If `path` is passed as a string, then -`writeStream.path` will be a string. If `path` is passed as a `Buffer`, then -`writeStream.path` will be a `Buffer`. +Aborting an ongoing request does not abort individual operating +system requests but rather the internal buffering `fs.writeFile` performs. -### `writeStream.pending` - +## Callback API -* {boolean} +The callback APIs perform all operations asynchronously, without blocking the +event loop, then invoke a callback function upon completion or error. -This property is `true` if the underlying file has not been opened yet, -i.e. before the `'ready'` event is emitted. +The callback APIs use the underlying Node.js threadpool to perform file +system operations off the event loop thread. These operations are not +synchronized or threadsafe. Care must be taken when performing multiple +concurrent modifications on the same file or data corruption may occur. -## `fs.access(path[, mode], callback)` +### `fs.access(path[, mode], callback)` - -* `path` {string|Buffer|URL} -* `mode` {integer} **Default:** `fs.constants.F_OK` - -Synchronously tests a user's permissions for the file or directory specified -by `path`. The `mode` argument is an optional integer that specifies the -accessibility checks to be performed. Check [File access constants][] for -possible values of `mode`. It is possible to create a mask consisting of -the bitwise OR of two or more values -(e.g. `fs.constants.W_OK | fs.constants.R_OK`). - -If any of the accessibility checks fail, an `Error` will be thrown. Otherwise, -the method will return `undefined`. - -```js -try { - fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK); - console.log('can read/write'); -} catch (err) { - console.error('no access!'); -} -``` - -## `fs.appendFile(path, data[, options], callback)` +### `fs.appendFile(path, data[, options], callback)` - -* `path` {string|Buffer|URL|number} filename or file descriptor -* `data` {string|Buffer} -* `options` {Object|string} - * `encoding` {string|null} **Default:** `'utf8'` - * `mode` {integer} **Default:** `0o666` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`. - -Synchronously append data to a file, creating the file if it does not yet -exist. `data` can be a string or a [`Buffer`][]. - -```js -try { - fs.appendFileSync('message.txt', 'data to append'); - console.log('The "data to append" was appended to file!'); -} catch (err) { - /* Handle the error */ } -``` - -If `options` is a string, then it specifies the encoding: - -```js -fs.appendFileSync('message.txt', 'data to append', 'utf8'); -``` - -The `path` may be specified as a numeric file descriptor that has been opened -for appending (using `fs.open()` or `fs.openSync()`). The file descriptor will -not be closed automatically. -```js -let fd; +open('message.txt', 'a', (err, fd) => { + if (err) throw err; -try { - fd = fs.openSync('message.txt', 'a'); - fs.appendFileSync(fd, 'data to append', 'utf8'); -} catch (err) { - /* Handle the error */ -} finally { - if (fd !== undefined) - fs.closeSync(fd); -} + try { + appendFile(fd, 'data to append', 'utf8', (err) => { + closeFd(fd); + if (err) throw err; + }); + } catch (err) { + closeFd(fd); + throw err; + } +}); ``` -## `fs.chmod(path, mode, callback)` +### `fs.chmod(path, mode, callback)` - -* `path` {string|Buffer|URL} -* `mode` {string|integer} - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.chmod()`][]. - -See also: chmod(2). - -## `fs.chown(path, uid, gid, callback)` - - -* `path` {string|Buffer|URL} -* `uid` {integer} -* `gid` {integer} - -Synchronously changes owner and group of a file. Returns `undefined`. -This is the synchronous version of [`fs.chown()`][]. +See the POSIX chown(2) documentation for more detail. -See also: chown(2). - -## `fs.close(fd[, callback])` +### `fs.close(fd[, callback])` - -* `fd` {integer} - -Synchronous close(2). Returns `undefined`. - -Calling `fs.closeSync()` on any file descriptor (`fd`) that is currently in use -through any other `fs` operation may lead to undefined behavior. - -## `fs.constants` - -* {Object} - -Returns an object containing commonly used constants for file system -operations. The specific constants currently defined are described in -[FS constants][]. +See the POSIX close(2) documentation for more detail. -## `fs.copyFile(src, dest[, mode], callback)` +### `fs.copyFile(src, dest[, mode], callback)` - -* `src` {string|Buffer|URL} source filename to copy -* `dest` {string|Buffer|URL} destination filename of the copy operation -* `mode` {integer} modifiers for copy operation. **Default:** `0`. - -Synchronously copies `src` to `dest`. By default, `dest` is overwritten if it -already exists. Returns `undefined`. Node.js makes no guarantees about the -atomicity of the copy operation. If an error occurs after the destination file -has been opened for writing, Node.js will attempt to remove the destination. - -`mode` is an optional integer that specifies the behavior -of the copy operation. It is possible to create a mask consisting of the bitwise -OR of two or more values (e.g. -`fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`). - -* `fs.constants.COPYFILE_EXCL`: The copy operation will fail if `dest` already - exists. -* `fs.constants.COPYFILE_FICLONE`: The copy operation will attempt to create a - copy-on-write reflink. If the platform does not support copy-on-write, then a - fallback copy mechanism is used. -* `fs.constants.COPYFILE_FICLONE_FORCE`: The copy operation will attempt to - create a copy-on-write reflink. If the platform does not support - copy-on-write, then the operation will fail. - -```js -const fs = require('fs'); -const { COPYFILE_EXCL } = fs.constants; - -// destination.txt will be created or overwritten by default. -fs.copyFileSync('source.txt', 'destination.txt'); -console.log('source.txt was copied to destination.txt'); +copyFile('source.txt', 'destination.txt', callback); // By using COPYFILE_EXCL, the operation will fail if destination.txt exists. -fs.copyFileSync('source.txt', 'destination.txt', COPYFILE_EXCL); +copyFile('source.txt', 'destination.txt', constants.COPYFILE_EXCL, callback); ``` -## `fs.createReadStream(path[, options])` +### `fs.createReadStream(path[, options])` - -* `path` {string|Buffer|URL} -* Returns: {boolean} - -Returns `true` if the path exists, `false` otherwise. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.exists()`][]. - -`fs.exists()` is deprecated, but `fs.existsSync()` is not. The `callback` -parameter to `fs.exists()` accepts parameters that are inconsistent with other -Node.js callbacks. `fs.existsSync()` does not use a callback. - -```js -if (fs.existsSync('/etc/passwd')) { - console.log('The path exists.'); -} -``` - -## `fs.fchmod(fd, mode, callback)` +### `fs.fchmod(fd, mode, callback)` - -* `fd` {integer} -* `mode` {string|integer} - -Synchronous fchmod(2). Returns `undefined`. +See the POSIX fchmod(2) documentation for more detail. -## `fs.fchown(fd, uid, gid, callback)` +### `fs.fchown(fd, uid, gid, callback)` - -* `fd` {integer} -* `uid` {integer} -* `gid` {integer} +Sets the owner of the file. No arguments other than a possible exception are +given to the completion callback. -Synchronous fchown(2). Returns `undefined`. +See the POSIX fchown(2) documentation for more detail. -## `fs.fdatasync(fd, callback)` +### `fs.fdatasync(fd, callback)` - -* `fd` {integer} - -Synchronous fdatasync(2). Returns `undefined`. +Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details. No arguments other than a possible +exception are given to the completion callback. -## `fs.fstat(fd[, options], callback)` +### `fs.fstat(fd[, options], callback)` - -* `fd` {integer} -* `options` {Object} - * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {fs.Stats} +Invokes the callback with the {fs.Stats} for the file descriptor. -Synchronous fstat(2). +See the POSIX fstat(2) documentation for more detail. -## `fs.fsync(fd, callback)` +### `fs.fsync(fd, callback)` - -* `fd` {integer} - -Synchronous fsync(2). Returns `undefined`. +Request that all data for the open file descriptor is flushed to the storage +device. The specific implementation is operating system and device specific. +Refer to the POSIX fsync(2) documentation for more detail. No arguments other +than a possible exception are given to the completion callback. -## `fs.ftruncate(fd[, len], callback)` +### `fs.ftruncate(fd[, len], callback)` - -* `fd` {integer} -* `len` {integer} **Default:** `0` - -Returns `undefined`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.ftruncate()`][]. - -## `fs.futimes(fd, atime, mtime, callback)` +### `fs.futimes(fd, atime, mtime, callback)` - -* `fd` {integer} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} - -Synchronous version of [`fs.futimes()`][]. Returns `undefined`. - -## `fs.lchmod(path, mode, callback)` +### `fs.lchmod(path, mode, callback)` +Changes the permissions on a symbolic link. No arguments other than a possible +exception are given to the completion callback. -* `path` {string|Buffer|URL} -* `mode` {integer} +This method is only implemented on macOS. -Synchronous lchmod(2). Returns `undefined`. +See the POSIX lchmod(2) documentation for more detail. -## `fs.lchown(path, uid, gid, callback)` +### `fs.lchown(path, uid, gid, callback)` - -* `path` {string|Buffer|URL} -* `uid` {integer} -* `gid` {integer} - -Synchronous lchown(2). Returns `undefined`. - -## `fs.lutimes(path, atime, mtime, callback)` - * `path` {string|Buffer|URL} @@ -2464,20 +2336,7 @@ symbolic link itself are changed. No arguments other than a possible exception are given to the completion callback. -## `fs.lutimesSync(path, atime, mtime)` - - -* `path` {string|Buffer|URL} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} - -Change the file system timestamps of the symbolic link referenced by `path`. -Returns `undefined`, or throws an exception when parameters are incorrect or -the operation fails. This is the synchronous version of [`fs.lutimes()`][]. - -## `fs.link(existingPath, newPath, callback)` +### `fs.link(existingPath, newPath, callback)` - -* `existingPath` {string|Buffer|URL} -* `newPath` {string|Buffer|URL} - -Synchronous link(2). Returns `undefined`. +Creates a new link from the `existingPath` to the `newPath`. See the POSIX +link(2) documentation for more detail. No arguments other than a possible +exception are given to the completion callback. -## `fs.lstat(path[, options], callback)` +### `fs.lstat(path[, options], callback)` - -* `path` {string|Buffer|URL} -* `options` {Object} - * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. - * `throwIfNoEntry` {boolean} Whether an exception will be thrown - if no file system entry exists, rather than returning `undefined`. - **Default:** `true`. -* Returns: {fs.Stats} +Retrieves the {fs.Stats} for the symbolic link refered to by the path. +The callback gets two arguments `(err, stats)` where `stats` is a {`fs.Stats} +object. `lstat()` is identical to `stat()`, except that if `path` is a symbolic +link, then the link itself is stat-ed, not the file that it refers to. -Synchronous lstat(2). +See the POSIX lstat(2) documentation for more details. -## `fs.mkdir(path[, options], callback)` +### `fs.mkdir(path[, options], callback)` - -* `path` {string|Buffer|URL} -* `options` {Object|integer} - * `recursive` {boolean} **Default:** `false` - * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. -* Returns: {string|undefined} - -Synchronously creates a directory. Returns `undefined`, or if `recursive` is -`true`, the first directory path created. -This is the synchronous version of [`fs.mkdir()`][]. +See the POSIX mkdir(2) documentation for more details. -See also: mkdir(2). - -## `fs.mkdtemp(prefix[, options], callback)` +### `fs.mkdtemp(prefix[, options], callback)` - -* `prefix` {string} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {string} - -Returns the created directory path. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.mkdtemp()`][]. - -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use. - -## `fs.open(path[, flags[, mode]], callback)` +### `fs.open(path[, flags[, mode]], callback)` - -* `path` {string|Buffer|URL} -* `options` {Object} - * `encoding` {string|null} **Default:** `'utf8'` - * `bufferSize` {number} Number of directory entries that are buffered - internally when reading from the directory. Higher values lead to better - performance but higher memory usage. **Default:** `32` -* Returns: {fs.Dir} - -Synchronously open a directory. See opendir(3). +Asynchronously open a directory. See the POSIX opendir(3) documentation for +more details. -Creates an [`fs.Dir`][], which contains all further functions for reading from +Creates an {fs.Dir}, which contains all further functions for reading from and cleaning up the directory. The `encoding` option sets the encoding for the `path` while opening the directory and subsequent read operations. -## `fs.openSync(path[, flags, mode])` - - -* `path` {string|Buffer|URL} -* `flags` {string|number} **Default:** `'r'`. - See [support of file system `flags`][]. -* `mode` {string|integer} **Default:** `0o666` -* Returns: {number} - -Returns an integer representing the file descriptor. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.open()`][]. - -## `fs.read(fd, buffer, offset, length, position, callback)` +### `fs.read(fd, buffer, offset, length, position, callback)` * `fd` {integer} -* `buffer` {Buffer|TypedArray|DataView} -* `offset` {integer} -* `length` {integer} -* `position` {integer|bigint} +* `buffer` {Buffer|TypedArray|DataView} The buffer that the data will be + written to. +* `offset` {integer} The position in `buffer` to write the data to. +* `length` {integer} The number of bytes to read. +* `position` {integer|bigint} Specifies where to begin reading from in the + file. If `position` is `null` or `-1 `, data will be read from the current + file position, and the file position will be updated. If `position` is an + integer, the file position will be unchanged. * `callback` {Function} * `err` {Error} * `bytesRead` {integer} @@ -2918,30 +2654,23 @@ changes: Read data from the file specified by `fd`. -`buffer` is the buffer that the data (read from the fd) will be written to. - -`offset` is the offset in the buffer to start writing at. - -`length` is an integer specifying the number of bytes to read. - -`position` is an argument specifying where to begin reading from in the file. -If `position` is `null`, data will be read from the current file position, -and the file position will be updated. -If `position` is an integer, the file position will remain unchanged. - The callback is given the three arguments, `(err, bytesRead, buffer)`. If the file is not modified concurrently, the end-of-file is reached when the number of bytes read is zero. If this method is invoked as its [`util.promisify()`][]ed version, it returns -a `Promise` for an `Object` with `bytesRead` and `buffer` properties. +a promise for an `Object` with `bytesRead` and `buffer` properties. -## `fs.read(fd, [options,] callback)` +### `fs.read(fd, [options,] callback)` - -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` - * `withFileTypes` {boolean} **Default:** `false` -* Returns: {string[]|Buffer[]|fs.Dirent[]} - -Synchronous readdir(3). +{fs.Dirent} objects. -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the filenames returned. If the `encoding` is set to `'buffer'`, -the filenames returned will be passed as `Buffer` objects. - -If `options.withFileTypes` is set to `true`, the result will contain -[`fs.Dirent`][] objects. - -## `fs.readFile(path[, options], callback)` +### `fs.readFile(path[, options], callback)` - -* `path` {string|Buffer|URL|integer} filename or file descriptor -* `options` {Object|string} - * `encoding` {string|null} **Default:** `null` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'r'`. -* Returns: {string|Buffer} - -Returns the contents of the `path`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.readFile()`][]. - -If the `encoding` option is specified then this function returns a -string. Otherwise it returns a buffer. - -Similar to [`fs.readFile()`][], when the path is a directory, the behavior of -`fs.readFileSync()` is platform-specific. - -```js -// macOS, Linux, and Windows -fs.readFileSync(''); -// => [Error: EISDIR: illegal operation on a directory, read ] - -// FreeBSD -fs.readFileSync(''); // => -``` - -## `fs.readlink(path[, options], callback)` +### `fs.readlink(path[, options], callback)` - -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {string|Buffer} - -Synchronous readlink(2). Returns the symbolic link's string value. - -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the link path returned. If the `encoding` is set to `'buffer'`, -the link path returned will be passed as a `Buffer` object. - -## `fs.readSync(fd, buffer, offset, length, position)` - - -* `fd` {integer} -* `buffer` {Buffer|TypedArray|DataView} -* `offset` {integer} -* `length` {integer} -* `position` {integer|bigint} -* Returns: {number} - -Returns the number of `bytesRead`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.read()`][]. - -## `fs.readSync(fd, buffer, [options])` - - -* `fd` {integer} -* `buffer` {Buffer|TypedArray|DataView} -* `options` {Object} - * `offset` {integer} **Default:** `0` - * `length` {integer} **Default:** `buffer.length` - * `position` {integer|bigint} **Default:** `null` -* Returns: {number} - -Returns the number of `bytesRead`. - -Similar to the above `fs.readSync` function, this version takes an optional `options` object. -If no `options` object is specified, it will default with the above values. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.read()`][]. - -## `fs.readv(fd, buffers[, position], callback)` - * `fd` {integer} @@ -3328,22 +2931,9 @@ The callback will be given three arguments: `err`, `bytesRead`, and `buffers`. `bytesRead` is how many bytes were read from the file. If this method is invoked as its [`util.promisify()`][]ed version, it returns -a `Promise` for an `Object` with `bytesRead` and `buffers` properties. - -## `fs.readvSync(fd, buffers[, position])` - - -* `fd` {integer} -* `buffers` {ArrayBufferView[]} -* `position` {integer} -* Returns: {number} The number of bytes read. +a promise for an `Object` with `bytesRead` and `buffers` properties. -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.readv()`][]. - -## `fs.realpath(path[, options], callback)` +### `fs.realpath(path[, options], callback)` @@ -3425,66 +3015,13 @@ Only paths that can be converted to UTF8 strings are supported. The optional `options` argument can be a string specifying an encoding, or an object with an `encoding` property specifying the character encoding to use for the path passed to the callback. If the `encoding` is set to `'buffer'`, -the path returned will be passed as a `Buffer` object. - -On Linux, when Node.js is linked against musl libc, the procfs file system must -be mounted on `/proc` in order for this function to work. Glibc does not have -this restriction. - -## `fs.realpathSync(path[, options])` - - -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {string|Buffer} - -Returns the resolved pathname. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.realpath()`][]. - -## `fs.realpathSync.native(path[, options])` - - -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {string|Buffer} - -Synchronous realpath(3). - -Only paths that can be converted to UTF8 strings are supported. - -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the path returned. If the `encoding` is set to `'buffer'`, -the path returned will be passed as a `Buffer` object. +the path returned will be passed as a {Buffer} object. On Linux, when Node.js is linked against musl libc, the procfs file system must be mounted on `/proc` in order for this function to work. Glibc does not have this restriction. -## `fs.rename(oldPath, newPath, callback)` +### `fs.rename(oldPath, newPath, callback)` - -* `oldPath` {string|Buffer|URL} -* `newPath` {string|Buffer|URL} - -Synchronous rename(2). Returns `undefined`. - -## `fs.rmdir(path[, options], callback)` +### `fs.rmdir(path[, options], callback)` - -* `path` {string|Buffer|URL} -* `options` {Object} - * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or - `EPERM` error is encountered, Node.js retries the operation with a linear - backoff wait of `retryDelay` milliseconds longer on each try. This option - represents the number of retries. This option is ignored if the `recursive` - option is not `true`. **Default:** `0`. - * `recursive` {boolean} If `true`, perform a recursive directory removal. In - recursive mode, errors are not reported if `path` does not exist, and - operations are retried on failure. **Default:** `false`. - * `retryDelay` {integer} The amount of time in milliseconds to wait between - retries. This option is ignored if the `recursive` option is not `true`. - **Default:** `100`. - -Synchronous rmdir(2). Returns `undefined`. - -Using `fs.rmdirSync()` on a file (not a directory) results in an `ENOENT` error -on Windows and an `ENOTDIR` error on POSIX. - -Setting `recursive` to `true` results in behavior similar to the Unix command -`rm -rf`: an error will not be raised for paths that do not exist, and paths -that represent files will be deleted. The permissive behavior of the -`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in -the future. - -## `fs.rm(path[, options], callback)` +### `fs.rm(path[, options], callback)` @@ -3672,30 +3147,7 @@ Asynchronously removes files and directories (modeled on the standard POSIX `rm` utility). No arguments other than a possible exception are given to the completion callback. -## `fs.rmSync(path[, options])` - - -* `path` {string|Buffer|URL} -* `options` {Object} - * `force` {boolean} When `true`, exceptions will be ignored if `path` does - not exist. **Default:** `false`. - * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or - `EPERM` error is encountered, Node.js will retry the operation with a linear - backoff wait of `retryDelay` milliseconds longer on each try. This option - represents the number of retries. This option is ignored if the `recursive` - option is not `true`. **Default:** `0`. - * `recursive` {boolean} If `true`, perform a recursive directory removal. In - recursive mode operations are retried on failure. **Default:** `false`. - * `retryDelay` {integer} The amount of time in milliseconds to wait between - retries. This option is ignored if the `recursive` option is not `true`. - **Default:** `100`. - -Synchronously removes files and directories (modeled on the standard POSIX `rm` -utility). Returns `undefined`. - -## `fs.stat(path[, options], callback)` +### `fs.stat(path[, options], callback)` - -* `path` {string|Buffer|URL} -* `options` {Object} - * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. - * `throwIfNoEntry` {boolean} Whether an exception will be thrown - if no file system entry exists, rather than returning `undefined`. - **Default:** `true`. -* Returns: {fs.Stats} - -Synchronous stat(2). - -## `fs.symlink(target, path[, type], callback)` +### `fs.symlink(target, path[, type], callback)` - -* `target` {string|Buffer|URL} -* `path` {string|Buffer|URL} -* `type` {string} - -Returns `undefined`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.symlink()`][]. - -## `fs.truncate(path[, len], callback)` +### `fs.truncate(path[, len], callback)` - -* `path` {string|Buffer|URL} -* `len` {integer} **Default:** `0` - -Synchronous truncate(2). Returns `undefined`. A file descriptor can also be -passed as the first argument. In this case, `fs.ftruncateSync()` is called. - -Passing a file descriptor is deprecated and may result in an error being thrown -in the future. - -## `fs.unlink(path, callback)` +See the POSIX truncate(2) documentation for more details. + +### `fs.unlink(path, callback)` - -* `path` {string|Buffer|URL} - -Synchronous unlink(2). Returns `undefined`. +See the POSIX unlink(2) documentation for more details. -## `fs.unwatchFile(filename[, listener])` +### `fs.unwatchFile(filename[, listener])` @@ -4017,7 +3398,7 @@ Using [`fs.watch()`][] is more efficient than `fs.watchFile()` and `fs.unwatchFile()`. `fs.watch()` should be used instead of `fs.watchFile()` and `fs.unwatchFile()` when possible. -## `fs.utimes(path, atime, mtime, callback)` +### `fs.utimes(path, atime, mtime, callback)` - -* `path` {string|Buffer|URL} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} - -Returns `undefined`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.utimes()`][]. - -## `fs.watch(filename[, options][, listener])` +### `fs.watch(filename[, options][, listener])` @@ -4151,7 +3505,7 @@ when the option is used on a platform that does not support it. On Windows, no events will be emitted if the watched directory is moved or renamed. An `EPERM` error is reported when the watched directory is deleted. -#### Availability +##### Availability @@ -4176,7 +3530,7 @@ when using virtualization software such as Vagrant or Docker. It is still possible to use `fs.watchFile()`, which uses stat polling, but this method is slower and less reliable. -#### Inodes +##### Inodes @@ -4190,7 +3544,7 @@ AIX files retain the same inode for the lifetime of a file. Saving and closing a watched file on AIX will result in two notifications (one for adding new content, and one for truncation). -#### Filename argument +##### Filename argument @@ -4199,8 +3553,9 @@ macOS, Windows, and AIX. Even on supported platforms, `filename` is not always guaranteed to be provided. Therefore, don't assume that `filename` argument is always provided in the callback, and have some fallback logic if it is `null`. -```js -fs.watch('somedir', (eventType, filename) => { +```js esm +import { watch } from 'fs'; +watch('somedir', (eventType, filename) => { console.log(`event type is: ${eventType}`); if (filename) { console.log(`filename provided: ${filename}`); @@ -4210,7 +3565,7 @@ fs.watch('somedir', (eventType, filename) => { }); ``` -## `fs.watchFile(filename[, options], listener)` +### `fs.watchFile(filename[, options], listener)` - -* `file` {string|Buffer|URL|integer} filename or file descriptor -* `data` {string|Buffer|TypedArray|DataView|Object} -* `options` {Object|string} - * `encoding` {string|null} **Default:** `'utf8'` - * `mode` {integer} **Default:** `0o666` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. - -Returns `undefined`. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.writeFile()`][]. - -## `fs.writeSync(fd, buffer[, offset[, length[, position]]])` - - -* `fd` {integer} -* `buffer` {Buffer|TypedArray|DataView|string|Object} -* `offset` {integer} -* `length` {integer} -* `position` {integer} -* Returns: {number} The number of bytes written. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.write(fd, buffer...)`][]. - -## `fs.writeSync(fd, string[, position[, encoding]])` - - -* `fd` {integer} -* `string` {string|Object} -* `position` {integer} -* `encoding` {string} -* Returns: {number} The number of bytes written. - -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.write(fd, string...)`][]. - -## `fs.writev(fd, buffers[, position], callback)` +### `fs.writev(fd, buffers[, position], callback)` @@ -4648,7 +3917,7 @@ at the current position. The callback will be given three arguments: `err`, `bytesWritten`, and `buffers`. `bytesWritten` is how many bytes were written from `buffers`. -If this method is [`util.promisify()`][]ed, it returns a `Promise` for an +If this method is [`util.promisify()`][]ed, it returns a promise for an `Object` with `bytesWritten` and `buffers` properties. It is unsafe to use `fs.writev()` multiple times on the same file without @@ -4658,235 +3927,269 @@ On Linux, positional writes don't work when the file is opened in append mode. The kernel ignores the position argument and always appends the data to the end of the file. -## `fs.writevSync(fd, buffers[, position])` - - -* `fd` {integer} -* `buffers` {ArrayBufferView[]} -* `position` {integer} -* Returns: {number} The number of bytes written. +## Synchronous API -For detailed information, see the documentation of the asynchronous version of -this API: [`fs.writev()`][]. +The synchronous APIs perform all operations synchronously, blocking the +event loop until the operation completes or fails. -## `fs` Promises API +### `fs.accessSync(path[, mode])` -The `fs.promises` API provides an alternative set of asynchronous file system -methods that return `Promise` objects rather than using callbacks. The -API is accessible via `require('fs').promises` or `require('fs/promises')`. - -### Class: `FileHandle` - +* `path` {string|Buffer|URL} +* `mode` {integer} **Default:** `fs.constants.F_OK` -A `FileHandle` object is a wrapper for a numeric file descriptor. -Instances of `FileHandle` are distinct from numeric file descriptors -in that they provide an object oriented API for working with files. +Synchronously tests a user's permissions for the file or directory specified +by `path`. The `mode` argument is an optional integer that specifies the +accessibility checks to be performed. Check [File access constants][] for +possible values of `mode`. It is possible to create a mask consisting of +the bitwise OR of two or more values +(e.g. `fs.constants.W_OK | fs.constants.R_OK`). -If a `FileHandle` is not closed using the -`filehandle.close()` method, it might automatically close the file descriptor -and will emit a process warning, thereby helping to prevent memory leaks. -Please do not rely on this behavior because it is unreliable and -the file may not be closed. Instead, always explicitly close `FileHandle`s. -Node.js may change this behavior in the future. +If any of the accessibility checks fail, an `Error` will be thrown. Otherwise, +the method will return `undefined`. -Instances of the `FileHandle` object are created internally by the -`fsPromises.open()` method. +```js esm +import { accessSync, constants } from 'fs'; -Unlike the callback-based API (`fs.fstat()`, `fs.fchown()`, `fs.fchmod()`, and -so on), a numeric file descriptor is not used by the promise-based API. Instead, -the promise-based API uses the `FileHandle` class in order to help avoid -accidental leaking of unclosed file descriptors after a `Promise` is fulfilled -or rejected. +try { + accessSync('etc/passwd', constants.R_OK | constants.W_OK); + console.log('can read/write'); +} catch (err) { + console.error('no access!'); +} +``` -#### `filehandle.appendFile(data, options)` +### `fs.appendFileSync(path, data[, options])` +* `path` {string|Buffer|URL|number} filename or file descriptor * `data` {string|Buffer} * `options` {Object|string} * `encoding` {string|null} **Default:** `'utf8'` -* Returns: {Promise} - -Alias of [`filehandle.writeFile()`][]. - -When operating on file handles, the mode cannot be changed from what it was set -to with [`fsPromises.open()`][]. Therefore, this is equivalent to -[`filehandle.writeFile()`][]. + * `mode` {integer} **Default:** `0o666` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`. -#### `filehandle.chmod(mode)` - +Synchronously append data to a file, creating the file if it does not yet +exist. `data` can be a string or a {Buffer}. -* `mode` {integer} -* Returns: {Promise} +```js esm +import { appendFileSync } from 'fs'; -Modifies the permissions on the file. The `Promise` is fulfilled with no -arguments upon success. +try { + appendFileSync('message.txt', 'data to append'); + console.log('The "data to append" was appended to file!'); +} catch (err) { + /* Handle the error */ +} +``` -#### `filehandle.chown(uid, gid)` - +If `options` is a string, then it specifies the encoding: -* `uid` {integer} -* `gid` {integer} -* Returns: {Promise} +```js esm +import { appendFileSync } from 'fs'; -Changes the ownership of the file then fulfills the `Promise` with no arguments -upon success. +appendFileSync('message.txt', 'data to append', 'utf8'); +``` -#### `filehandle.close()` - +The `path` may be specified as a numeric file descriptor that has been opened +for appending (using `fs.open()` or `fs.openSync()`). The file descriptor will +not be closed automatically. -* Returns: {Promise} A `Promise` that will be fulfilled once the underlying - file descriptor is closed, or will be rejected if an error occurs while - closing. +```js esm +import { openSync, closeSync, appendFileSync } from 'fs'; -Closes the file handle after waiting for any pending operation on the handle to -complete. +let fd; -```js -const fsPromises = require('fs').promises; -async function openAndClose() { - let filehandle; - try { - filehandle = await fsPromises.open('thefile.txt', 'r'); - } finally { - if (filehandle !== undefined) - await filehandle.close(); - } +try { + fd = openSync('message.txt', 'a'); + appendFileSync(fd, 'data to append', 'utf8'); +} catch (err) { + /* Handle the error */ +} finally { + if (fd !== undefined) + closeSync(fd); } ``` -#### `filehandle.datasync()` +### `fs.chmodSync(path, mode)` -* Returns: {Promise} +* `path` {string|Buffer|URL} +* `mode` {string|integer} + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.chmod()`][]. -Asynchronous fdatasync(2). The `Promise` is fulfilled with no arguments upon -success. +See the POSIX chmod(2) documentation for more detail. -#### `filehandle.fd` +### `fs.chownSync(path, uid, gid)` -* {number} The numeric file descriptor managed by the `FileHandle` object. +* `path` {string|Buffer|URL} +* `uid` {integer} +* `gid` {integer} + +Synchronously changes owner and group of a file. Returns `undefined`. +This is the synchronous version of [`fs.chown()`][]. -#### `filehandle.read(buffer, offset, length, position)` +See the POSIX chown(2) documentation for more detail. + +### `fs.closeSync(fd)` -* `buffer` {Buffer|Uint8Array} -* `offset` {integer} -* `length` {integer} -* `position` {integer} -* Returns: {Promise} +* `fd` {integer} -Read data from the file. +Closes the file descriptor. Returns `undefined`. -`buffer` is the buffer that the data will be written to. +Calling `fs.closeSync()` on any file descriptor (`fd`) that is currently in use +through any other `fs` operation may lead to undefined behavior. -`offset` is the offset in the buffer to start writing at. +See the POSIX close(2) documentation for more detail. -`length` is an integer specifying the number of bytes to read. +### `fs.copyFileSync(src, dest[, mode])` + -`position` is an argument specifying where to begin reading from in the file. -If `position` is `null`, data will be read from the current file position, -and the file position will be updated. -If `position` is an integer, the file position will remain unchanged. +* `src` {string|Buffer|URL} source filename to copy +* `dest` {string|Buffer|URL} destination filename of the copy operation +* `mode` {integer} modifiers for copy operation. **Default:** `0`. -Following successful read, the `Promise` is fulfilled with an object with a -`bytesRead` property specifying the number of bytes read, and a `buffer` -property that is a reference to the passed in `buffer` argument. +Synchronously copies `src` to `dest`. By default, `dest` is overwritten if it +already exists. Returns `undefined`. Node.js makes no guarantees about the +atomicity of the copy operation. If an error occurs after the destination file +has been opened for writing, Node.js will attempt to remove the destination. -If the file is not modified concurrently, the end-of-file is reached when the -number of bytes read is zero. +`mode` is an optional integer that specifies the behavior +of the copy operation. It is possible to create a mask consisting of the bitwise +OR of two or more values (e.g. +`fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`). -#### `filehandle.read(options)` - -* `options` {Object} - * `buffer` {Buffer|Uint8Array} **Default:** `Buffer.alloc(16384)` - * `offset` {integer} **Default:** `0` - * `length` {integer} **Default:** `buffer.length` - * `position` {integer} **Default:** `null` -* Returns: {Promise} +* `fs.constants.COPYFILE_EXCL`: The copy operation will fail if `dest` already + exists. +* `fs.constants.COPYFILE_FICLONE`: The copy operation will attempt to create a + copy-on-write reflink. If the platform does not support copy-on-write, then a + fallback copy mechanism is used. +* `fs.constants.COPYFILE_FICLONE_FORCE`: The copy operation will attempt to + create a copy-on-write reflink. If the platform does not support + copy-on-write, then the operation will fail. -#### `filehandle.readFile(options)` +```js esm +import { copyFileSync, constants } from 'fs'; + +// destination.txt will be created or overwritten by default. +copyFileSync('source.txt', 'destination.txt'); +console.log('source.txt was copied to destination.txt'); + +// By using COPYFILE_EXCL, the operation will fail if destination.txt exists. +copyFileSync('source.txt', 'destination.txt', constants.COPYFILE_EXCL); +``` + +### `fs.existsSync(path)` -* `options` {Object|string} - * `encoding` {string|null} **Default:** `null` - * `signal` {AbortSignal} allows aborting an in-progress readFile -* Returns: {Promise} +* `path` {string|Buffer|URL} +* Returns: {boolean} -Asynchronously reads the entire contents of a file. +Returns `true` if the path exists, `false` otherwise. -The `Promise` is fulfilled with the contents of the file. If no encoding is -specified (using `options.encoding`), the data is returned as a `Buffer` -object. Otherwise, the data will be a string. +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.exists()`][]. -If `options` is a string, then it specifies the encoding. +`fs.exists()` is deprecated, but `fs.existsSync()` is not. The `callback` +parameter to `fs.exists()` accepts parameters that are inconsistent with other +Node.js callbacks. `fs.existsSync()` does not use a callback. -The `FileHandle` has to support reading. +```js esm +import { existsSync } from 'fs'; -If one or more `filehandle.read()` calls are made on a file handle and then a -`filehandle.readFile()` call is made, the data will be read from the current -position till the end of the file. It doesn't always read from the beginning -of the file. +if (existsSync('/etc/passwd')) + console.log('The path exists.'); +``` -#### `filehandle.readv(buffers[, position])` +### `fs.fchmodSync(fd, mode)` -* `buffers` {ArrayBufferView[]} -* `position` {integer} -* Returns: {Promise} +* `fd` {integer} +* `mode` {string|integer} -Read from a file and write to an array of `ArrayBufferView`s +Sets the permissions on the file. Returns `undefined`. -The `Promise` is fulfilled with an object containing a `bytesRead` property -identifying the number of bytes read, and a `buffers` property containing -a reference to the `buffers` input. +See the POSIX fchmod(2) documentation for more detail. -`position` is the offset from the beginning of the file where this data -should be read from. If `typeof position !== 'number'`, the data will be read -from the current position. +### `fs.fchownSync(fd, uid, gid)` + -#### `filehandle.stat([options])` +* `fd` {integer} +* `uid` {integer} The file's new owner's user id. +* `gid` {integer} The file's new group's group id. + +Sets the owner of the file. Returns `undefined`. + +See the POSIX fchown(2) documentation for more detail. + +### `fs.fdatasyncSync(fd)` + +* `fd` {integer} + +Forces all currently queued I/O operations associated with the file to the +operating system's synchronized I/O completion state. Refer to the POSIX +fdatasync(2) documentation for details. Returns `undefined`. + +### `fs.fstatSync(fd[, options])` + +* `fd` {integer} * `options` {Object} * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {Promise} + {fs.Stats} object should be `bigint`. **Default:** `false`. +* Returns: {fs.Stats} -Retrieves the [`fs.Stats`][] for the file. +Retrieves the {fs.Stats} for the file descriptor. -#### `filehandle.sync()` +See the POSIX fstat(2) documentation for more detail. + +### `fs.fsyncSync(fd)` -* Returns: {Promise} +* `fd` {integer} -Asynchronous fsync(2). The `Promise` is fulflled with no arguments upon -success. +Request that all data for the open file descriptor is flushed to the storage +device. The specific implementation is operating system and device specific. +Refer to the POSIX fsync(2) documentation for more detail. Returns `undefined`. -#### `filehandle.truncate(len)` +### `fs.ftruncateSync(fd[, len])` +* `fd` {integer} * `len` {integer} **Default:** `0` -* Returns: {Promise} -Truncates the file then fulfills the `Promise` with no arguments upon success. +Truncates the file descriptor. Returns `undefined`. -If the file was larger than `len` bytes, only the first `len` bytes will be -retained in the file. +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.ftruncate()`][]. -For example, the following program retains only the first four bytes of the -file: +### `fs.futimesSync(fd, atime, mtime)` + -```js -const fs = require('fs'); -const fsPromises = fs.promises; +* `fd` {integer} +* `atime` {number|string|Date} +* `mtime` {number|string|Date} -console.log(fs.readFileSync('temp.txt', 'utf8')); -// Prints: Node.js +Synchronous version of [`fs.futimes()`][]. Returns `undefined`. -async function doTruncate() { - let filehandle = null; - try { - filehandle = await fsPromises.open('temp.txt', 'r+'); - await filehandle.truncate(4); - } finally { - if (filehandle) { - // Close the file if it is opened. - await filehandle.close(); - } - } - console.log(fs.readFileSync('temp.txt', 'utf8')); // Prints: Node -} +### `fs.lchmodSync(path, mode)` + -doTruncate().catch(console.error); -``` +* `path` {string|Buffer|URL} +* `mode` {integer} -If the file previously was shorter than `len` bytes, it is extended, and the -extended part is filled with null bytes (`'\0'`): +Changes the permissions on a symbolic link. Returns `undefined`. -```js -const fs = require('fs'); -const fsPromises = fs.promises; +This method is only implemented on macOS. -console.log(fs.readFileSync('temp.txt', 'utf8')); -// Prints: Node.js +See the POSIX lchmod(2) documentation for more detail. -async function doTruncate() { - let filehandle = null; - try { - filehandle = await fsPromises.open('temp.txt', 'r+'); - await filehandle.truncate(10); - } finally { - if (filehandle) { - // Close the file if it is opened. - await filehandle.close(); - } - } - console.log(fs.readFileSync('temp.txt', 'utf8')); // Prints Node.js\0\0\0 -} +### `fs.lchownSync(path, uid, gid)` + -doTruncate().catch(console.error); -``` +* `path` {string|Buffer|URL} +* `uid` {integer} The file's new owner's user id. +* `gid` {integer} The file's new group's group id. -The last three bytes are null bytes (`'\0'`), to compensate the over-truncation. +Set the owner for the path. Returns `undefined`. -#### `filehandle.utimes(atime, mtime)` +See the POSIX lchown(2) documentation for more details. + +### `fs.lutimesSync(path, atime, mtime)` +* `path` {string|Buffer|URL} * `atime` {number|string|Date} * `mtime` {number|string|Date} -* Returns: {Promise} - -Change the file system timestamps of the object referenced by the `FileHandle` -then fulfills the `Promise` with no arguments upon success. -This function does not work on AIX versions before 7.1, it will reject the -`Promise` with an error using code `UV_ENOSYS`. +Change the file system timestamps of the symbolic link referenced by `path`. +Returns `undefined`, or throws an exception when parameters are incorrect or +the operation fails. This is the synchronous version of [`fs.lutimes()`][]. -#### `filehandle.write(buffer[, offset[, length[, position]]])` +### `fs.linkSync(existingPath, newPath)` -* `buffer` {Buffer|Uint8Array|string|Object} -* `offset` {integer} -* `length` {integer} -* `position` {integer} -* Returns: {Promise} +* `existingPath` {string|Buffer|URL} +* `newPath` {string|Buffer|URL} -Write `buffer` to the file. +Creates a new link from the `existingPath` to the `newPath`. See the POSIX +link(2) documentation for more detail. Returns `undefined`. -The `Promise` is fulfilled with an object containing a `bytesWritten` property -identifying the number of bytes written, and a `buffer` property containing -a reference to the `buffer` written. +### `fs.lstatSync(path[, options])` + -`offset` determines the part of the buffer to be written, and `length` is -an integer specifying the number of bytes to write. +* `path` {string|Buffer|URL} +* `options` {Object} + * `bigint` {boolean} Whether the numeric values in the returned + {fs.Stats} object should be `bigint`. **Default:** `false`. + * `throwIfNoEntry` {boolean} Whether an exception will be thrown + if no file system entry exists, rather than returning `undefined`. + **Default:** `true`. +* Returns: {fs.Stats} + +Retrieves the {fs.Stats} for the symbolic link refered to by `path`. + +See the POSIX lstat(2) documentation for more details. + +### `fs.mkdirSync(path[, options])` + + +* `path` {string|Buffer|URL} +* `options` {Object|integer} + * `recursive` {boolean} **Default:** `false` + * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. +* Returns: {string|undefined} + +Synchronously creates a directory. Returns `undefined`, or if `recursive` is +`true`, the first directory path created. +This is the synchronous version of [`fs.mkdir()`][]. + +See the POSIX mkdir(2) documentation for more details. + +### `fs.mkdtempSync(prefix[, options])` + + +* `prefix` {string} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {string} + +Returns the created directory path. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.mkdtemp()`][]. + +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use. + +### `fs.opendirSync(path[, options])` + + +* `path` {string|Buffer|URL} +* `options` {Object} + * `encoding` {string|null} **Default:** `'utf8'` + * `bufferSize` {number} Number of directory entries that are buffered + internally when reading from the directory. Higher values lead to better + performance but higher memory usage. **Default:** `32` +* Returns: {fs.Dir} + +Synchronously open a directory. See opendir(3). + +Creates an {fs.Dir}, which contains all further functions for reading from +and cleaning up the directory. + +The `encoding` option sets the encoding for the `path` while opening the +directory and subsequent read operations. + +### `fs.openSync(path[, flags, mode])` + + +* `path` {string|Buffer|URL} +* `flags` {string|number} **Default:** `'r'`. + See [support of file system `flags`][]. +* `mode` {string|integer} **Default:** `0o666` +* Returns: {number} + +Returns an integer representing the file descriptor. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.open()`][]. + +### `fs.readdirSync(path[, options])` + + +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` + * `withFileTypes` {boolean} **Default:** `false` +* Returns: {string[]|Buffer[]|fs.Dirent[]} + +Reads the contents of the director. + +See the POSIX readdir(3) documentation for more details. + +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the filenames returned. If the `encoding` is set to `'buffer'`, +the filenames returned will be passed as {Buffer} objects. + +If `options.withFileTypes` is set to `true`, the result will contain +{fs.Dirent} objects. + +### `fs.readFileSync(path[, options])` + + +* `path` {string|Buffer|URL|integer} filename or file descriptor +* `options` {Object|string} + * `encoding` {string|null} **Default:** `null` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'r'`. +* Returns: {string|Buffer} + +Returns the contents of the `path`. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.readFile()`][]. + +If the `encoding` option is specified then this function returns a +string. Otherwise it returns a buffer. + +Similar to [`fs.readFile()`][], when the path is a directory, the behavior of +`fs.readFileSync()` is platform-specific. + +```js esm +import { readFileSync } from 'fs'; + +// macOS, Linux, and Windows +readFileSync(''); +// => [Error: EISDIR: illegal operation on a directory, read ] + +// FreeBSD +readFileSync(''); // => +``` + +### `fs.readlinkSync(path[, options])` + + +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {string|Buffer} + +Returns the symbolic link's string value. + +See the POSIX readlink(2) documentation for more details. + +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the link path returned. If the `encoding` is set to `'buffer'`, +the link path returned will be passed as a {Buffer} object. + +### `fs.readSync(fd, buffer, offset, length, position)` + + +* `fd` {integer} +* `buffer` {Buffer|TypedArray|DataView} +* `offset` {integer} +* `length` {integer} +* `position` {integer|bigint} +* Returns: {number} + +Returns the number of `bytesRead`. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.read()`][]. + +### `fs.readSync(fd, buffer, [options])` + + +* `fd` {integer} +* `buffer` {Buffer|TypedArray|DataView} +* `options` {Object} + * `offset` {integer} **Default:** `0` + * `length` {integer} **Default:** `buffer.length` + * `position` {integer|bigint} **Default:** `null` +* Returns: {number} + +Returns the number of `bytesRead`. + +Similar to the above `fs.readSync` function, this version takes an optional `options` object. +If no `options` object is specified, it will default with the above values. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.read()`][]. + +### `fs.readvSync(fd, buffers[, position])` + + +* `fd` {integer} +* `buffers` {ArrayBufferView[]} +* `position` {integer} +* Returns: {number} The number of bytes read. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.readv()`][]. + +### `fs.realpathSync(path[, options])` + + +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {string|Buffer} + +Returns the resolved pathname. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.realpath()`][]. + +### `fs.realpathSync.native(path[, options])` + + +* `path` {string|Buffer|URL} +* `options` {string|Object} + * `encoding` {string} **Default:** `'utf8'` +* Returns: {string|Buffer} + +Synchronous realpath(3). + +Only paths that can be converted to UTF8 strings are supported. + +The optional `options` argument can be a string specifying an encoding, or an +object with an `encoding` property specifying the character encoding to use for +the path returned. If the `encoding` is set to `'buffer'`, +the path returned will be passed as a {Buffer} object. + +On Linux, when Node.js is linked against musl libc, the procfs file system must +be mounted on `/proc` in order for this function to work. Glibc does not have +this restriction. + +### `fs.renameSync(oldPath, newPath)` + + +* `oldPath` {string|Buffer|URL} +* `newPath` {string|Buffer|URL} + +Renames the file from `oldPath` to `newPath`. Returns `undefined`. + +See the POSIX rename(2) documentation for more details. + +### `fs.rmdirSync(path[, options])` + + +* `path` {string|Buffer|URL} +* `options` {Object} + * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or + `EPERM` error is encountered, Node.js retries the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. + * `recursive` {boolean} If `true`, perform a recursive directory removal. In + recursive mode, errors are not reported if `path` does not exist, and + operations are retried on failure. **Default:** `false`. + * `retryDelay` {integer} The amount of time in milliseconds to wait between + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. + +Synchronous rmdir(2). Returns `undefined`. + +Using `fs.rmdirSync()` on a file (not a directory) results in an `ENOENT` error +on Windows and an `ENOTDIR` error on POSIX. + +Setting `recursive` to `true` results in behavior similar to the Unix command +`rm -rf`: an error will not be raised for paths that do not exist, and paths +that represent files will be deleted. The permissive behavior of the +`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in +the future. + +### `fs.rmSync(path[, options])` + + +* `path` {string|Buffer|URL} +* `options` {Object} + * `force` {boolean} When `true`, exceptions will be ignored if `path` does + not exist. **Default:** `false`. + * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or + `EPERM` error is encountered, Node.js will retry the operation with a linear + backoff wait of `retryDelay` milliseconds longer on each try. This option + represents the number of retries. This option is ignored if the `recursive` + option is not `true`. **Default:** `0`. + * `recursive` {boolean} If `true`, perform a recursive directory removal. In + recursive mode operations are retried on failure. **Default:** `false`. + * `retryDelay` {integer} The amount of time in milliseconds to wait between + retries. This option is ignored if the `recursive` option is not `true`. + **Default:** `100`. + +Synchronously removes files and directories (modeled on the standard POSIX `rm` +utility). Returns `undefined`. + +### `fs.statSync(path[, options])` + + +* `path` {string|Buffer|URL} +* `options` {Object} + * `bigint` {boolean} Whether the numeric values in the returned + {fs.Stats} object should be `bigint`. **Default:** `false`. + * `throwIfNoEntry` {boolean} Whether an exception will be thrown + if no file system entry exists, rather than returning `undefined`. + **Default:** `true`. +* Returns: {fs.Stats} + +Retrieves the {fs.Stats} for the path. + +### `fs.symlinkSync(target, path[, type])` + + +* `target` {string|Buffer|URL} +* `path` {string|Buffer|URL} +* `type` {string} + +Returns `undefined`. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.symlink()`][]. + +### `fs.truncateSync(path[, len])` + + +* `path` {string|Buffer|URL} +* `len` {integer} **Default:** `0` + +Truncates the file. Returns `undefined`. A file descriptor can also be +passed as the first argument. In this case, `fs.ftruncateSync()` is called. + +Passing a file descriptor is deprecated and may result in an error being thrown +in the future. + +### `fs.unlinkSync(path)` + + +* `path` {string|Buffer|URL} + +Synchronous unlink(2). Returns `undefined`. + +### `fs.utimesSync(path, atime, mtime)` + + +* `path` {string|Buffer|URL} +* `atime` {number|string|Date} +* `mtime` {number|string|Date} + +Returns `undefined`. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.utimes()`][]. + +### `fs.writeFileSync(file, data[, options])` + + +* `file` {string|Buffer|URL|integer} filename or file descriptor +* `data` {string|Buffer|TypedArray|DataView|Object} +* `options` {Object|string} + * `encoding` {string|null} **Default:** `'utf8'` + * `mode` {integer} **Default:** `0o666` + * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. + +Returns `undefined`. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.writeFile()`][]. + +### `fs.writeSync(fd, buffer[, offset[, length[, position]]])` + + +* `fd` {integer} +* `buffer` {Buffer|TypedArray|DataView|string|Object} +* `offset` {integer} +* `length` {integer} +* `position` {integer} +* Returns: {number} The number of bytes written. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.write(fd, buffer...)`][]. + +### `fs.writeSync(fd, string[, position[, encoding]])` + + +* `fd` {integer} +* `string` {string|Object} +* `position` {integer} +* `encoding` {string} +* Returns: {number} The number of bytes written. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.write(fd, string...)`][]. + +### `fs.writevSync(fd, buffers[, position])` + + +* `fd` {integer} +* `buffers` {ArrayBufferView[]} +* `position` {integer} +* Returns: {number} The number of bytes written. + +For detailed information, see the documentation of the asynchronous version of +this API: [`fs.writev()`][]. + +## Common Objects + +The common objects are shared by all of the file system API variants +(promise, callback, and synchronous). + +### Class: `fs.Dir` + + +A class representing a directory stream. + +Created by [`fs.opendir()`][], [`fs.opendirSync()`][], or +[`fsPromises.opendir()`][]. + +```js esm +import { opendir } from 'fs/promises'; + +try { + const dir = await opendir('./'); + for await (const dirent of dir) + console.log(dirent.name); +} catch (err) { + console.error(err); +} +``` + +#### `dir.close()` + + +* Returns: {Promise} + +Asynchronously close the directory's underlying resource handle. +Subsequent reads will result in errors. + +A promise is returned that will be resolved after the resource has been +closed. + +#### `dir.close(callback)` + + +* `callback` {Function} + * `err` {Error} + +Asynchronously close the directory's underlying resource handle. +Subsequent reads will result in errors. + +The `callback` will be called after the resource handle has been closed. + +#### `dir.closeSync()` + + +Synchronously close the directory's underlying resource handle. +Subsequent reads will result in errors. + +#### `dir.path` + + +* {string} + +The read-only path of this directory as was provided to [`fs.opendir()`][], +[`fs.opendirSync()`][], or [`fsPromises.opendir()`][]. + +#### `dir.read()` + + +* Returns: {Promise} containing {fs.Dirent|null} + +Asynchronously read the next directory entry via readdir(3) as an +{fs.Dirent}. + +A promise is returned that will be resolved with an {fs.Dirent}, or `null` +if there are no more directory entries to read. + +Directory entries returned by this function are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results. + +#### `dir.read(callback)` + + +* `callback` {Function} + * `err` {Error} + * `dirent` {fs.Dirent|null} + +Asynchronously read the next directory entry via readdir(3) as an +{fs.Dirent}. + +After the read is completed, the `callback` will be called with an +{fs.Dirent}, or `null` if there are no more directory entries to read. + +Directory entries returned by this function are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results. + +#### `dir.readSync()` + + +* Returns: {fs.Dirent|null} + +Synchronously read the next directory entry as an {fs.Dirent}. See the +POSIX readdir(3) documentation for more detail. + +If there are no more directory entries to read, `null` will be returned. + +Directory entries returned by this function are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results. + +#### `dir[Symbol.asyncIterator]()` + + +* Returns: {AsyncIterator} of {fs.Dirent} + +Asynchronously iterates over the directory until all entries have +been read. Refer to the POSIX readdir(3) documentation for more detail. + +Entries returned by the async iterator are always an {fs.Dirent}. +The `null` case from `dir.read()` is handled internally. + +See {fs.Dir} for an example. + +Directory entries returned by this iterator are in no particular order as +provided by the operating system's underlying directory mechanisms. +Entries added or removed while iterating over the directory might not be +included in the iteration results. + +### Class: `fs.Dirent` + + +A representation of a directory entry, which can be a file or a subdirectory +within the directory, as returned by reading from an {fs.Dir}. The +directory entry is a combination of the file name and file type pairs. + +Additionally, when [`fs.readdir()`][] or [`fs.readdirSync()`][] is called with +the `withFileTypes` option set to `true`, the resulting array is filled with +{fs.Dirent} objects, rather than strings or {Buffer}s. + +#### `dirent.isBlockDevice()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a block device. + +#### `dirent.isCharacterDevice()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a character device. + +#### `dirent.isDirectory()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a file system +directory. + +#### `dirent.isFIFO()` + + +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a first-in-first-out +(FIFO) pipe. + +#### `dirent.isFile()` + -`position` refers to the offset from the beginning of the file where this data -should be written. If `typeof position !== 'number'`, the data will be written -at the current position. See pwrite(2). +* Returns: {boolean} -It is unsafe to use `filehandle.write()` multiple times on the same file -without waiting for the `Promise` to be fulfilled (or rejected). For this -scenario, use [`fs.createWriteStream()`][]. +Returns `true` if the {fs.Dirent} object describes a regular file. -On Linux, positional writes do not work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file. +#### `dirent.isSocket()` + -#### `filehandle.write(string[, position[, encoding]])` +* Returns: {boolean} + +Returns `true` if the {fs.Dirent} object describes a socket. + +#### `dirent.isSymbolicLink()` -* `string` {string|Object} -* `position` {integer} -* `encoding` {string} **Default:** `'utf8'` -* Returns: {Promise} +* Returns: {boolean} -Write `string` to the file. If `string` is not a string, or an -object with an own `toString` function property, then an exception is thrown. +Returns `true` if the {fs.Dirent} object describes a symbolic link. -The `Promise` is fulfilled with an object containing a `bytesWritten` property -identifying the number of bytes written, and a `buffer` property containing -a reference to the `string` written. +#### `dirent.name` + -`position` refers to the offset from the beginning of the file where this data -should be written. If the type of `position` is not a `number` the data -will be written at the current position. See pwrite(2). +* {string|Buffer} -`encoding` is the expected string encoding. +The file name that this {fs.Dirent} object refers to. The type of this +value is determined by the `options.encoding` passed to [`fs.readdir()`][] or +[`fs.readdirSync()`][]. -It is unsafe to use `filehandle.write()` multiple times on the same file -without waiting for the `Promise` to be fulfilled (or rejected). For this -scenario, use [`fs.createWriteStream()`][]. +### Class: `fs.FSWatcher` + -On Linux, positional writes do not work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file. +* Extends {EventEmitter} -#### `filehandle.writeFile(data, options)` +A successful call to [`fs.watch()`][] method will return a new {fs.FSWatcher} +object. + +All {fs.FSWatcher} objects emit a `'change'` event whenever a specific watched +file is modified. + +#### Event: `'change'` -* `data` {string|Buffer|Uint8Array|Object} -* `options` {Object|string} - * `encoding` {string|null} **Default:** `'utf8'` -* Returns: {Promise} +* `eventType` {string} The type of change event that has occurred +* `filename` {string|Buffer} The filename that changed (if relevant/available) -Asynchronously writes data to a file, replacing the file if it already exists. -`data` can be a string, a buffer, or an object with an own `toString` function -property. The `Promise` is fulfilled with no arguments upon success. +Emitted when something changes in a watched directory or file. +See more details in [`fs.watch()`][]. -The `encoding` option is ignored if `data` is a buffer. +The `filename` argument may not be provided depending on operating system +support. If `filename` is provided, it will be provided as a {Buffer} if +`fs.watch()` is called with its `encoding` option set to `'buffer'`, otherwise +`filename` will be a UTF-8 string. -If `options` is a string, then it specifies the encoding. +```js esm +import { watch } from 'fs'; +// Example when handled through fs.watch() listener +watch('./tmp', { encoding: 'buffer' }, (eventType, filename) => { + if (filename) { + console.log(filename); + // Prints: + } +}); +``` -The `FileHandle` has to support writing. +#### Event: `'close'` + -It is unsafe to use `filehandle.writeFile()` multiple times on the same file -without waiting for the `Promise` to be fulfilled (or rejected). +Emitted when the watcher stops watching for changes. The closed +{fs.FSWatcher} object is no longer usable in the event handler. -If one or more `filehandle.write()` calls are made on a file handle and then a -`filehandle.writeFile()` call is made, the data will be written from the -current position till the end of the file. It doesn't always write from the -beginning of the file. +#### Event: `'error'` + -#### `filehandle.writev(buffers[, position])` +* `error` {Error} + +Emitted when an error occurs while watching the file. The errored +{fs.FSWatcher} object is no longer usable in the event handler. + +#### `watcher.close()` -* `buffers` {ArrayBufferView[]} -* `position` {integer} -* Returns: {Promise} +Stop watching for changes on the given {fs.FSWatcher}. Once stopped, the +{fs.FSWatcher} object is no longer usable. -Write an array of `ArrayBufferView`s to the file. +#### `watcher.ref()` + -The `Promise` is fulfilled with an object containing a `bytesWritten` property -identifying the number of bytes written, and a `buffers` property containing -a reference to the `buffers` input. +* Returns: {fs.FSWatcher} -`position` is the offset from the beginning of the file where this data -should be written. If `typeof position !== 'number'`, the data will be written -at the current position. +When called, requests that the Node.js event loop *not* exit so long as the +{fs.FSWatcher} is active. Calling `watcher.ref()` multiple times will have +no effect. -It is unsafe to call `writev()` multiple times on the same file without waiting -for the previous operation to complete. +By default, all {fs.FSWatcher} objects are "ref'ed", making it normally +unnecessary to call `watcher.ref()` unless `watcher.unref()` had been +called previously. -On Linux, positional writes don't work when the file is opened in append mode. -The kernel ignores the position argument and always appends the data to -the end of the file. +#### `watcher.unref()` + -### `fsPromises.access(path[, mode])` +* Returns: {fs.FSWatcher} + +When called, the active {fs.FSWatcher} object will not require the Node.js +event loop to remain active. If there is no other activity keeping the +event loop running, the process may exit before the {fs.FSWatcher} object's +callback is invoked. Calling `watcher.unref()` multiple times will have +no effect. + +### Class: `fs.StatWatcher` -* `path` {string|Buffer|URL} -* `mode` {integer} **Default:** `fs.constants.F_OK` -* Returns: {Promise} +* Extends {EventEmitter} -Tests a user's permissions for the file or directory specified by `path`. -The `mode` argument is an optional integer that specifies the accessibility -checks to be performed. Check [File access constants][] for possible values -of `mode`. It is possible to create a mask consisting of the bitwise OR of -two or more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`). +A successful call to `fs.watchFile()` method will return a new {fs.StatWatcher} +object. -If the accessibility check is successful, the `Promise` is fulfilled with no -value. If any of the accessibility checks fail, the `Promise` is rejected -with an `Error` object. The following example checks if the file -`/etc/passwd` can be read and written by the current process. +#### `watcher.ref()` + -```js -const fs = require('fs'); -const fsPromises = fs.promises; +* Returns: {fs.StatWatcher} -fsPromises.access('/etc/passwd', fs.constants.R_OK | fs.constants.W_OK) - .then(() => console.log('can access')) - .catch(() => console.error('cannot access')); -``` +When called, requests that the Node.js event loop *not* exit so long as the +{fs.StatWatcher} is active. Calling `watcher.ref()` multiple times will have +no effect. -Using `fsPromises.access()` to check for the accessibility of a file before -calling `fsPromises.open()` is not recommended. Doing so introduces a race -condition, since other processes may change the file's state between the two -calls. Instead, user code should open/read/write the file directly and handle -the error raised if the file is not accessible. +By default, all {fs.StatWatcher} objects are "ref'ed", making it normally +unnecessary to call `watcher.ref()` unless `watcher.unref()` had been +called previously. -### `fsPromises.appendFile(path, data[, options])` +#### `watcher.unref()` -* `path` {string|Buffer|URL|FileHandle} filename or `FileHandle` -* `data` {string|Buffer} -* `options` {Object|string} - * `encoding` {string|null} **Default:** `'utf8'` - * `mode` {integer} **Default:** `0o666` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'a'`. -* Returns: {Promise} +* Returns: {fs.StatWatcher} -Asynchronously append data to a file, creating the file if it does not yet -exist. `data` can be a string or a [`Buffer`][]. The `Promise` will be -fulfilled with no arguments upon success. +When called, the active {fs.StatWatcher} object will not require the Node.js +event loop to remain active. If there is no other activity keeping the +event loop running, the process may exit before the {fs.StatWatcher} object's +callback is invoked. Calling `watcher.unref()` multiple times will have +no effect. -If `options` is a string, then it specifies the encoding. +### Class: `fs.ReadStream` + -The `path` may be specified as a `FileHandle` that has been opened -for appending (using `fsPromises.open()`). +* Extends: {stream.Readable} -### `fsPromises.chmod(path, mode)` +Instances of {fs.ReadStream} are created and returned using the +[`fs.createReadStream()`][] function. + +#### Event: `'close'` -* `path` {string|Buffer|URL} -* `mode` {string|integer} -* Returns: {Promise} +Emitted when the {fs.ReadStream}'s underlying file descriptor has been closed. + +#### Event: `'open'` + -Changes the permissions of a file then fulfills the `Promise` with no -arguments upon succces. +* `fd` {integer} Integer file descriptor used by the {fs.ReadStream}. -### `fsPromises.chown(path, uid, gid)` +Emitted when the {fs.ReadStream}'s file descriptor has been opened. + +#### Event: `'ready'` -* `path` {string|Buffer|URL} -* `uid` {integer} -* `gid` {integer} -* Returns: {Promise} +Emitted when the {fs.ReadStream} is ready to be used. -Changes the ownership of a file then fulfills the `Promise` with no arguments -upon success. +Fires immediately after `'open'`. -### `fsPromises.copyFile(src, dest[, mode])` +#### `readStream.bytesRead` -* `src` {string|Buffer|URL} source filename to copy -* `dest` {string|Buffer|URL} destination filename of the copy operation -* `mode` {integer} modifiers for copy operation. **Default:** `0`. -* Returns: {Promise} +* {number} -Asynchronously copies `src` to `dest`. By default, `dest` is overwritten if it -already exists. The `Promise` will be fulfilled with no arguments upon success. +The number of bytes that have been read so far. + +#### `readStream.path` + -Node.js makes no guarantees about the atomicity of the copy operation. If an -error occurs after the destination file has been opened for writing, Node.js -will attempt to remove the destination. +* {string|Buffer} -`mode` is an optional integer that specifies the behavior -of the copy operation. It is possible to create a mask consisting of the bitwise -OR of two or more values (e.g. -`fs.constants.COPYFILE_EXCL | fs.constants.COPYFILE_FICLONE`). +The path to the file the stream is reading from as specified in the first +argument to `fs.createReadStream()`. If `path` is passed as a string, then +`readStream.path` will be a string. If `path` is passed as a {Buffer}, then +`readStream.path` will be a {Buffer}. -* `fs.constants.COPYFILE_EXCL`: The copy operation will fail if `dest` already - exists. -* `fs.constants.COPYFILE_FICLONE`: The copy operation will attempt to create a - copy-on-write reflink. If the platform does not support copy-on-write, then a - fallback copy mechanism is used. -* `fs.constants.COPYFILE_FICLONE_FORCE`: The copy operation will attempt to - create a copy-on-write reflink. If the platform does not support - copy-on-write, then the operation will fail. +#### `readStream.pending` + + +* {boolean} + +This property is `true` if the underlying file has not been opened yet, +i.e. before the `'ready'` event is emitted. + +### Class: `fs.Stats` + -```js -const { - promises: fsPromises, - constants: { - COPYFILE_EXCL - } -} = require('fs'); +A {fs.Stats} object provides information about a file. -// destination.txt will be created or overwritten by default. -fsPromises.copyFile('source.txt', 'destination.txt') - .then(() => console.log('source.txt was copied to destination.txt')) - .catch(() => console.log('The file could not be copied')); +Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and +their synchronous counterparts are of this type. +If `bigint` in the `options` passed to those methods is true, the numeric values +will be `bigint` instead of `number`, and the object will contain additional +nanosecond-precision properties suffixed with `Ns`. -// By using COPYFILE_EXCL, the operation will fail if destination.txt exists. -fsPromises.copyFile('source.txt', 'destination.txt', COPYFILE_EXCL) - .then(() => console.log('source.txt was copied to destination.txt')) - .catch(() => console.log('The file could not be copied')); +```console +Stats { + dev: 2114, + ino: 48064969, + mode: 33188, + nlink: 1, + uid: 85, + gid: 100, + rdev: 0, + size: 527, + blksize: 4096, + blocks: 8, + atimeMs: 1318289051000.1, + mtimeMs: 1318289051000.1, + ctimeMs: 1318289051000.1, + birthtimeMs: 1318289051000.1, + atime: Mon, 10 Oct 2011 23:24:11 GMT, + mtime: Mon, 10 Oct 2011 23:24:11 GMT, + ctime: Mon, 10 Oct 2011 23:24:11 GMT, + birthtime: Mon, 10 Oct 2011 23:24:11 GMT } ``` -### `fsPromises.lchmod(path, mode)` +`bigint` version: + +```console +BigIntStats { + dev: 2114n, + ino: 48064969n, + mode: 33188n, + nlink: 1n, + uid: 85n, + gid: 100n, + rdev: 0n, + size: 527n, + blksize: 4096n, + blocks: 8n, + atimeMs: 1318289051000n, + mtimeMs: 1318289051000n, + ctimeMs: 1318289051000n, + birthtimeMs: 1318289051000n, + atimeNs: 1318289051000000000n, + mtimeNs: 1318289051000000000n, + ctimeNs: 1318289051000000000n, + birthtimeNs: 1318289051000000000n, + atime: Mon, 10 Oct 2011 23:24:11 GMT, + mtime: Mon, 10 Oct 2011 23:24:11 GMT, + ctime: Mon, 10 Oct 2011 23:24:11 GMT, + birthtime: Mon, 10 Oct 2011 23:24:11 GMT } +``` + +#### `stats.isBlockDevice()` -* `path` {string|Buffer|URL} -* `mode` {integer} -* Returns: {Promise} +* Returns: {boolean} -Changes the permissions on a symbolic link then fulfills the `Promise` with -no arguments upon success. This method is only implemented on macOS. +Returns `true` if the {fs.Stats} object describes a block device. -### `fsPromises.lchown(path, uid, gid)` +#### `stats.isCharacterDevice()` -* `path` {string|Buffer|URL} -* `uid` {integer} -* `gid` {integer} -* Returns: {Promise} +* Returns: {boolean} -Changes the ownership on a symbolic link then fulfills the `Promise` with -no arguments upon success. +Returns `true` if the {fs.Stats} object describes a character device. -### `fsPromises.lutimes(path, atime, mtime)` +#### `stats.isDirectory()` -* `path` {string|Buffer|URL} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} -* Returns: {Promise} +* Returns: {boolean} -Changes the access and modification times of a file in the same way as -[`fsPromises.utimes()`][], with the difference that if the path refers to a -symbolic link, then the link is not dereferenced: instead, the timestamps of -the symbolic link itself are changed. +Returns `true` if the {fs.Stats} object describes a file system directory. -Upon success, the `Promise` is fulfilled without arguments. +If the {fs.Stats} object was obtained from [`fs.lstat()`][], this method will +always return `false`. This is because [`fs.lstat()`][] returns information +about a symbolic link itself and not the path it resolves to. -### `fsPromises.link(existingPath, newPath)` +#### `stats.isFIFO()` -* `existingPath` {string|Buffer|URL} -* `newPath` {string|Buffer|URL} -* Returns: {Promise} +* Returns: {boolean} -Asynchronous link(2). The `Promise` is fulfilled with no arguments upon success. +Returns `true` if the {fs.Stats} object describes a first-in-first-out (FIFO) +pipe. -### `fsPromises.lstat(path[, options])` +#### `stats.isFile()` -* `path` {string|Buffer|URL} -* `options` {Object} - * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {Promise} +* Returns: {boolean} -Asynchronous lstat(2). The `Promise` is fulfilled with the [`fs.Stats`][] -object for the given symbolic link `path`. +Returns `true` if the {fs.Stats} object describes a regular file. -### `fsPromises.mkdir(path[, options])` +#### `stats.isSocket()` -* `path` {string|Buffer|URL} -* `options` {Object|integer} - * `recursive` {boolean} **Default:** `false` - * `mode` {string|integer} Not supported on Windows. **Default:** `0o777`. -* Returns: {Promise} - -Asynchronously creates a directory then fulfills the `Promise` with either no -arguments, or the first directory path created if `recursive` is `true`. +* Returns: {boolean} -The optional `options` argument can be an integer specifying `mode` (permission -and sticky bits), or an object with a `mode` property and a `recursive` -property indicating whether parent directories should be created. Calling -`fsPromises.mkdir()` when `path` is a directory that exists results in a -rejection only when `recursive` is false. +Returns `true` if the {fs.Stats} object describes a socket. -### `fsPromises.mkdtemp(prefix[, options])` +#### `stats.isSymbolicLink()` -* `prefix` {string} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {Promise} - -Creates a unique temporary directory and fulfills the `Promise` with the -created directory path. A unique directory name is generated by appending six -random characters to the end of the provided `prefix`. Due to platform -inconsistencies, avoid trailing `X` characters in `prefix`. Some platforms, -notably the BSDs, can return more than six random characters, and replace -trailing `X` characters in `prefix` with random characters. - -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use. +* Returns: {boolean} -```js -fsPromises.mkdtemp(path.join(os.tmpdir(), 'foo-')) - .catch(console.error); -``` +Returns `true` if the {fs.Stats} object describes a symbolic link. -The `fsPromises.mkdtemp()` method will append the six randomly selected -characters directly to the `prefix` string. For instance, given a directory -`/tmp`, if the intention is to create a temporary directory *within* `/tmp`, the -`prefix` must end with a trailing platform-specific path separator -(`require('path').sep`). +This method is only valid when using [`fs.lstat()`][]. -### `fsPromises.open(path, flags[, mode])` - +#### `stats.dev` -* `path` {string|Buffer|URL} -* `flags` {string|number} See [support of file system `flags`][]. - **Default:** `'r'`. -* `mode` {string|integer} **Default:** `0o666` (readable and writable) -* Returns: {Promise} +* {number|bigint} -Asynchronous file open that returns a `Promise` that, when fulfilled, yields a -`FileHandle` object. See open(2). +The numeric identifier of the device containing the file. -`mode` sets the file mode (permission and sticky bits), but only if the file was -created. +#### `stats.ino` -Some characters (`< > : " / \ | ? *`) are reserved under Windows as documented -by [Naming Files, Paths, and Namespaces][]. Under NTFS, if the filename contains -a colon, Node.js will open a file system stream, as described by -[this MSDN page][MSDN-Using-Streams]. +* {number|bigint} -### `fsPromises.opendir(path[, options])` - +The file system specific "Inode" number for the file. -* `path` {string|Buffer|URL} -* `options` {Object} - * `encoding` {string|null} **Default:** `'utf8'` - * `bufferSize` {number} Number of directory entries that are buffered - internally when reading from the directory. Higher values lead to better - performance but higher memory usage. **Default:** `32` -* Returns: {Promise} containing {fs.Dir} +#### `stats.mode` -Asynchronously open a directory. See opendir(3). +* {number|bigint} -Creates an [`fs.Dir`][], which contains all further functions for reading from -and cleaning up the directory. +A bit-field describing the file type and mode. -The `encoding` option sets the encoding for the `path` while opening the -directory and subsequent read operations. +#### `stats.nlink` -Example using async iteration: +* {number|bigint} -```js -const fs = require('fs'); +The number of hard-links that exist for the file. -async function print(path) { - const dir = await fs.promises.opendir(path); - for await (const dirent of dir) { - console.log(dirent.name); - } -} -print('./').catch(console.error); -``` +#### `stats.uid` -### `fsPromises.readdir(path[, options])` - +* {number|bigint} -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` - * `withFileTypes` {boolean} **Default:** `false` -* Returns: {Promise} +The numeric user identifier of the user that owns the file (POSIX). -Reads the contents of a directory then fulfills the `Promise` with an array -of the names of the files in the directory excluding `'.'` and `'..'`. +#### `stats.gid` -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the filenames. If the `encoding` is set to `'buffer'`, the filenames returned -will be passed as `Buffer` objects. +* {number|bigint} -If `options.withFileTypes` is set to `true`, the array will contain -[`fs.Dirent`][] objects. +The numeric group identifier of the group that owns the file (POSIX). -```js -const fs = require('fs'); +#### `stats.rdev` -async function print(path) { - const files = await fs.promises.readdir(path); - for (const file of files) { - console.log(file); - } -} -print('./').catch(console.error); -``` +* {number|bigint} -### `fsPromises.readFile(path[, options])` - +A numeric device identifier if the file represents a device. -* `path` {string|Buffer|URL|FileHandle} filename or `FileHandle` -* `options` {Object|string} - * `encoding` {string|null} **Default:** `null` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'r'`. - * `signal` {AbortSignal} allows aborting an in-progress readFile -* Returns: {Promise} +#### `stats.size` -Asynchronously reads the entire contents of a file. +* {number|bigint} -The `Promise` is fulfilled with the contents of the file. If no encoding is -specified (using `options.encoding`), the data is returned as a `Buffer` -object. Otherwise, the data will be a string. +The size of the file in bytes. -If `options` is a string, then it specifies the encoding. +#### `stats.blksize` -When the `path` is a directory, the behavior of `fsPromises.readFile()` is -platform-specific. On macOS, Linux, and Windows, the promise will be rejected -with an error. On FreeBSD, a representation of the directory's contents will be -returned. +* {number|bigint} -It is possible to abort an ongoing `readFile` using an `AbortSignal`. If a -request is aborted the promise returned is rejected with an `AbortError`: +The file system block size for i/o operations. -```js -const controller = new AbortController(); -const signal = controller.signal; -readFile(fileName, { signal }).then((file) => { /* ... */ }); -// Abort the request -controller.abort(); -``` +#### `stats.blocks` -Aborting an ongoing request does not abort individual operating -system requests but rather the internal buffering `fs.readFile` performs. +* {number|bigint} -Any specified `FileHandle` has to support reading. +The number of blocks allocated for this file. -### `fsPromises.readlink(path[, options])` +#### `stats.atimeMs` -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {Promise} - -Asynchronous readlink(2). The `Promise` is fulfilled with the `linkString` upon -success. +* {number|bigint} -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the link path returned. If the `encoding` is set to `'buffer'`, the link path -returned will be passed as a `Buffer` object. +The timestamp indicating the last time this file was accessed expressed in +milliseconds since the POSIX Epoch. -### `fsPromises.realpath(path[, options])` +#### `stats.mtimeMs` -* `path` {string|Buffer|URL} -* `options` {string|Object} - * `encoding` {string} **Default:** `'utf8'` -* Returns: {Promise} +* {number|bigint} -Determines the actual location of `path` using the same semantics as the -`fs.realpath.native()` function then fulfills the `Promise` with the resolved -path. +The timestamp indicating the last time this file was modified expressed in +milliseconds since the POSIX Epoch. -Only paths that can be converted to UTF8 strings are supported. +#### `stats.ctimeMs` + -The optional `options` argument can be a string specifying an encoding, or an -object with an `encoding` property specifying the character encoding to use for -the path. If the `encoding` is set to `'buffer'`, the path returned will be -passed as a `Buffer` object. +* {number|bigint} -On Linux, when Node.js is linked against musl libc, the procfs file system must -be mounted on `/proc` in order for this function to work. Glibc does not have -this restriction. +The timestamp indicating the last time the file status was changed expressed +in milliseconds since the POSIX Epoch. -### `fsPromises.rename(oldPath, newPath)` +#### `stats.birthtimeMs` -* `oldPath` {string|Buffer|URL} -* `newPath` {string|Buffer|URL} -* Returns: {Promise} +* {number|bigint} -Renames `oldPath` to `newPath` and fulfills the `Promise` with no arguments -upon success. +The timestamp indicating the creation time of this file expressed in +milliseconds since the POSIX Epoch. -### `fsPromises.rmdir(path[, options])` +#### `stats.atimeNs` -* `path` {string|Buffer|URL} -* `options` {Object} - * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or - `EPERM` error is encountered, Node.js retries the operation with a linear - backoff wait of `retryDelay` milliseconds longer on each try. This option - represents the number of retries. This option is ignored if the `recursive` - option is not `true`. **Default:** `0`. - * `recursive` {boolean} If `true`, perform a recursive directory removal. In - recursive mode, errors are not reported if `path` does not exist, and - operations are retried on failure. **Default:** `false`. - * `retryDelay` {integer} The amount of time in milliseconds to wait between - retries. This option is ignored if the `recursive` option is not `true`. - **Default:** `100`. -* Returns: {Promise} +* {bigint} -Removes the directory identified by `path` then fulfills the `Promise` with -no arguments upon success. +Only present when `bigint: true` is passed into the method that generates +the object. +The timestamp indicating the last time this file was accessed expressed in +nanoseconds since the POSIX Epoch. -Using `fsPromises.rmdir()` on a file (not a directory) results in the -`Promise` being rejected with an `ENOENT` error on Windows and an `ENOTDIR` -error on POSIX. +#### `stats.mtimeNs` + -Setting `recursive` to `true` results in behavior similar to the Unix command -`rm -rf`: an error will not be raised for paths that do not exist, and paths -that represent files will be deleted. The permissive behavior of the -`recursive` option is deprecated, `ENOTDIR` and `ENOENT` will be thrown in -the future. +* {bigint} -### `fsPromises.rm(path[, options])` +Only present when `bigint: true` is passed into the method that generates +the object. +The timestamp indicating the last time this file was modified expressed in +nanoseconds since the POSIX Epoch. + +#### `stats.ctimeNs` -* `path` {string|Buffer|URL} -* `options` {Object} - * `force` {boolean} When `true`, exceptions will be ignored if `path` does - not exist. **Default:** `false`. - * `maxRetries` {integer} If an `EBUSY`, `EMFILE`, `ENFILE`, `ENOTEMPTY`, or - `EPERM` error is encountered, Node.js will retry the operation with a linear - backoff wait of `retryDelay` milliseconds longer on each try. This option - represents the number of retries. This option is ignored if the `recursive` - option is not `true`. **Default:** `0`. - * `recursive` {boolean} If `true`, perform a recursive directory removal. In - recursive mode operations are retried on failure. **Default:** `false`. - * `retryDelay` {integer} The amount of time in milliseconds to wait between - retries. This option is ignored if the `recursive` option is not `true`. - **Default:** `100`. +* {bigint} -Removes files and directories (modeled on the standard POSIX `rm` utility). -Fulfills the `Promise` with no arguments on success. +Only present when `bigint: true` is passed into the method that generates +the object. +The timestamp indicating the last time the file status was changed expressed +in nanoseconds since the POSIX Epoch. -### `fsPromises.stat(path[, options])` +#### `stats.birthtimeNs` -* `path` {string|Buffer|URL} -* `options` {Object} - * `bigint` {boolean} Whether the numeric values in the returned - [`fs.Stats`][] object should be `bigint`. **Default:** `false`. -* Returns: {Promise} +* {bigint} -The `Promise` is fulfilled with the [`fs.Stats`][] object for the given `path`. +Only present when `bigint: true` is passed into the method that generates +the object. +The timestamp indicating the creation time of this file expressed in +nanoseconds since the POSIX Epoch. -### `fsPromises.symlink(target, path[, type])` +#### `stats.atime` -* `target` {string|Buffer|URL} -* `path` {string|Buffer|URL} -* `type` {string} **Default:** `'file'` -* Returns: {Promise} +* {Date} -Creates a symbolic link then fulfills the `Promise` with no arguments upon -success. +The timestamp indicating the last time this file was accessed. -The `type` argument is only used on Windows platforms and can be one of `'dir'`, -`'file'`, or `'junction'`. Windows junction points require the destination path -to be absolute. When using `'junction'`, the `target` argument will -automatically be normalized to absolute path. +#### `stats.mtime` + -### `fsPromises.truncate(path[, len])` +* {Date} + +The timestamp indicating the last time this file was modified. + +#### `stats.ctime` -* `path` {string|Buffer|URL} -* `len` {integer} **Default:** `0` -* Returns: {Promise} +* {Date} -Truncates the `path` then fulfills the `Promise` with no arguments upon -success. The `path` *must* be a string or `Buffer`. +The timestamp indicating the last time the file status was changed. -### `fsPromises.unlink(path)` +#### `stats.birthtime` -* `path` {string|Buffer|URL} -* Returns: {Promise} +* {Date} -Asynchronous unlink(2). The `Promise` is fulfilled with no arguments upon -success. +The timestamp indicating the creation time of this file. -### `fsPromises.utimes(path, atime, mtime)` +#### Stat time values + +The `atimeMs`, `mtimeMs`, `ctimeMs`, `birthtimeMs` properties are +numeric values that hold the corresponding times in milliseconds. Their +precision is platform specific. When `bigint: true` is passed into the +method that generates the object, the properties will be [bigints][], +otherwise they will be [numbers][MDN-Number]. + +The `atimeNs`, `mtimeNs`, `ctimeNs`, `birthtimeNs` properties are +[bigints][] that hold the corresponding times in nanoseconds. They are +only present when `bigint: true` is passed into the method that generates +the object. Their precision is platform specific. + +`atime`, `mtime`, `ctime`, and `birthtime` are +[`Date`][MDN-Date] object alternate representations of the various times. The +`Date` and number values are not connected. Assigning a new number value, or +mutating the `Date` value, will not be reflected in the corresponding alternate +representation. + +The times in the stat object have the following semantics: + +* `atime` "Access Time": Time when file data last accessed. Changed + by the mknod(2), utimes(2), and read(2) system calls. +* `mtime` "Modified Time": Time when file data last modified. + Changed by the mknod(2), utimes(2), and write(2) system calls. +* `ctime` "Change Time": Time when file status was last changed + (inode data modification). Changed by the chmod(2), chown(2), + link(2), mknod(2), rename(2), unlink(2), utimes(2), + read(2), and write(2) system calls. +* `birthtime` "Birth Time": Time of file creation. Set once when the + file is created. On filesystems where birthtime is not available, + this field may instead hold either the `ctime` or + `1970-01-01T00:00Z` (ie, Unix epoch timestamp `0`). This value may be greater + than `atime` or `mtime` in this case. On Darwin and other FreeBSD variants, + also set if the `atime` is explicitly set to an earlier value than the current + `birthtime` using the utimes(2) system call. + +Prior to Node.js 0.12, the `ctime` held the `birthtime` on Windows systems. As +of 0.12, `ctime` is not "creation time", and on Unix systems, it never was. + +### Class: `fs.WriteStream` -* `path` {string|Buffer|URL} -* `atime` {number|string|Date} -* `mtime` {number|string|Date} -* Returns: {Promise} +* Extends {stream.Writable} -Change the file system timestamps of the object referenced by `path` then -fulfills the `Promise` with no arguments upon success. +Instances of {fs.WriteStream} are created and returned using the +[`fs.createWriteStream()`][] function. -The `atime` and `mtime` arguments follow these rules: +#### Event: `'close'` + -* Values can be either numbers representing Unix epoch time, `Date`s, or a - numeric string like `'123456789.0'`. -* If the value can not be converted to a number, or is `NaN`, `Infinity` or - `-Infinity`, an `Error` will be thrown. +Emitted when the {fs.WriteStream}'s underlying file descriptor has been closed. -### `fsPromises.writeFile(file, data[, options])` +#### Event: `'open'` -* `file` {string|Buffer|URL|FileHandle} filename or `FileHandle` -* `data` {string|Buffer|Uint8Array|Object} -* `options` {Object|string} - * `encoding` {string|null} **Default:** `'utf8'` - * `mode` {integer} **Default:** `0o666` - * `flag` {string} See [support of file system `flags`][]. **Default:** `'w'`. - * `signal` {AbortSignal} allows aborting an in-progress writeFile -* Returns: {Promise} +* `fd` {integer} Integer file descriptor used by the {fs.WriteStream}. -Asynchronously writes data to a file, replacing the file if it already exists. -`data` can be a string, a buffer, or an object with an own `toString` function -property. The `Promise` is fulfilled with no arguments upon success. +Emitted when the {fs.WriteStream}'s file is opened. -The `encoding` option is ignored if `data` is a buffer. +#### Event: `'ready'` + -If `options` is a string, then it specifies the encoding. +Emitted when the {fs.WriteStream} is ready to be used. -Any specified `FileHandle` has to support writing. +Fires immediately after `'open'`. -It is unsafe to use `fsPromises.writeFile()` multiple times on the same file -without waiting for the `Promise` to be fulfilled (or rejected). +#### `writeStream.bytesWritten` + -Similarly to `fsPromises.readFile` - `fsPromises.writeFile` is a convenience -method that performs multiple `write` calls internally to write the buffer -passed to it. For performance sensitive code consider using -[`fs.createWriteStream()`][]. +The number of bytes written so far. Does not include data that is still queued +for writing. -It is possible to use an {AbortSignal} to cancel an `fsPromises.writeFile()`. -Cancelation is "best effort", and some amount of data is likely still -to be written. +#### `writeStream.path` + -```js -const controller = new AbortController(); -const { signal } = controller; -const data = new Uint8Array(Buffer.from('Hello Node.js')); -(async () => { - try { - await fs.writeFile('message.txt', data, { signal }); - } catch (err) { - // When a request is aborted - err is an AbortError - } -})(); -// When the request should be aborted -controller.abort(); -``` +The path to the file the stream is writing to as specified in the first +argument to [`fs.createWriteStream()`][]. If `path` is passed as a string, then +`writeStream.path` will be a string. If `path` is passed as a {Buffer}, then +`writeStream.path` will be a {Buffer}. -Aborting an ongoing request does not abort individual operating -system requests but rather the internal buffering `fs.writeFile` performs. +#### `writeStream.pending` + + +* {boolean} + +This property is `true` if the underlying file has not been opened yet, +i.e. before the `'ready'` event is emitted. -## FS constants +### `fs.constants` + +* {Object} + +Returns an object containing commonly used constants for file system +operations. + +#### FS constants The following constants are exported by `fs.constants`. @@ -5835,21 +5856,21 @@ To use more than one constant, use the bitwise OR `|` operator. Example: -```js -const fs = require('fs'); +```js esm +import { open, constants } from 'fs'; const { O_RDWR, O_CREAT, O_EXCL -} = fs.constants; +} = constants; -fs.open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => { +open('/path/to/my/file', O_RDWR | O_CREAT | O_EXCL, (err, fd) => { // ... }); ``` -### File access constants +##### File access constants The following constants are meant for use with [`fs.access()`][]. @@ -5881,7 +5902,7 @@ The following constants are meant for use with [`fs.access()`][]. -### File copy constants +##### File copy constants The following constants are meant for use with [`fs.copyFile()`][]. @@ -5909,7 +5930,7 @@ The following constants are meant for use with [`fs.copyFile()`][]. -### File open constants +##### File open constants The following constants are meant for use with `fs.open()`. @@ -6003,9 +6024,9 @@ The following constants are meant for use with `fs.open()`. -### File type constants +##### File type constants -The following constants are meant for use with the [`fs.Stats`][] object's +The following constants are meant for use with the {fs.Stats} object's `mode` property for determining a file's type. @@ -6047,9 +6068,9 @@ The following constants are meant for use with the [`fs.Stats`][] object's
-### File mode constants +##### File mode constants -The following constants are meant for use with the [`fs.Stats`][] object's +The following constants are meant for use with the {fs.Stats} object's `mode` property for determining the access permissions for a file. @@ -6107,7 +6128,323 @@ The following constants are meant for use with the [`fs.Stats`][] object's
-## File system flags +## Notes + +### Ordering of callback and promise-based operations + +Because they are executed asynchronously by the underlying thread pool, +there is no guaranteed ordering when using either the callback or +promise-based methods. + +For example, the following is prone to error because the `fs.stat()` +operation might complete before the `fs.rename()` operation: + +```js +fs.rename('/tmp/hello', '/tmp/world', (err) => { + if (err) throw err; + console.log('renamed complete'); +}); +fs.stat('/tmp/world', (err, stats) => { + if (err) throw err; + console.log(`stats: ${JSON.stringify(stats)}`); +}); +``` + +It is important to correctly order the operations by awaiting the results +of one before invoking the other: + +```js esm +// Using ESM syntax +import { rename, stat } from 'fs/promises'; + +const from = '/tmp/hello'; +const to = '/tmp/world'; + +try { + await rename(from, to); + const stats = await stat(to); + console.log(`stats: ${JSON.stringify(stats)}`); +} catch (error) { + console.error('there was an error:', error.message); +} +``` + +```js cjs +// Using CommonJS syntax +const { rename, stat } = require('fs/promises'); + +(async function(from, to) { + try { + await rename(from, to); + const stats = await stat(to); + console.log(`stats: ${JSON.stringify(stats)}`); + } catch (error) { + console.error('there was an error:', error.message); + } +})('/tmp/hello', '/tmp/world'); +``` + +Or, when using the callback APIs, move the `fs.stat()` call into the callback +of the `fs.rename()` operation: + +```js esm +import { rename, stat } from 'fs'; + +rename('/tmp/hello', '/tmp/world', (err) => { + if (err) throw err; + stat('/tmp/world', (err, stats) => { + if (err) throw err; + console.log(`stats: ${JSON.stringify(stats)}`); + }); +}); +``` + +```js cjs +const { rename, stat } = require('fs/promises'); + +rename('/tmp/hello', '/tmp/world', (err) => { + if (err) throw err; + stat('/tmp/world', (err, stats) => { + if (err) throw err; + console.log(`stats: ${JSON.stringify(stats)}`); + }); +}); +``` + +### File paths + +Most `fs` operations accept file paths that may be specified in the form of +a string, a {Buffer}, or a {URL} object using the `file:` protocol. + +#### String paths + +String form paths are interpreted as UTF-8 character sequences identifying +the absolute or relative filename. Relative paths will be resolved relative +to the current working directory as determined by calling `process.cwd()`. + +Example using an absolute path on POSIX: + +```js esm +import { open } from 'fs/promises'; + +let fd; +try { + fd = await open('/open/some/file.txt', 'r'); + // Do something with the file +} finally { + await fd.close(); +} +``` + +Example using a relative path on POSIX (relative to `process.cwd()`): + +```js esm +import { open } from 'fs/promises'; + +let fd; +try { + fd = await open('file.txt', 'r'); + // Do something with the file +} finally { + await fd.close(); +} +``` + +#### File URL paths + +For most `fs` module functions, the `path` or `filename` argument may be passed +as a {URL} object using the `file:` protocol. + +```js esm +import { readFileSync } from 'fs'; + +readFileSync(new URL('file:///tmp/hello')); +``` + +`file:` URLs are always absolute paths. + +##### Platform-specific considerations + +On Windows, `file:` {URL}s with a host name convert to UNC paths, while `file:` +{URL}s with drive letters convert to local absolute paths. `file:` {URL}s +without a host name nor a drive letter will result in an error: + +```js esm +import { readFileSync } from 'fs'; +// On Windows : + +// - WHATWG file URLs with hostname convert to UNC path +// file://hostname/p/a/t/h/file => \\hostname\p\a\t\h\file +readFileSync(new URL('file://hostname/p/a/t/h/file')); + +// - WHATWG file URLs with drive letters convert to absolute path +// file:///C:/tmp/hello => C:\tmp\hello +readFileSync(new URL('file:///C:/tmp/hello')); + +// - WHATWG file URLs without hostname must have a drive letters +readFileSync(new URL('file:///notdriveletter/p/a/t/h/file')); +readFileSync(new URL('file:///c/p/a/t/h/file')); +// TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute +``` + +`file:` {URL}s with drive letters must use `:` as a separator just after +the drive letter. Using another separator will result in an error. + +On all other platforms, `file:` {URL}s with a host name are unsupported and +will result in an error: + +```js esm +import { readFileSync } from 'fs'; +// On other platforms: + +// - WHATWG file URLs with hostname are unsupported +// file://hostname/p/a/t/h/file => throw! +readFileSync(new URL('file://hostname/p/a/t/h/file')); +// TypeError [ERR_INVALID_FILE_URL_PATH]: must be absolute + +// - WHATWG file URLs convert to absolute path +// file:///tmp/hello => /tmp/hello +readFileSync(new URL('file:///tmp/hello')); +``` + +A `file:` {URL} having encoded slash characters will result in an error on all +platforms: + +```js esm +import { readFileSync } from 'fs'; + +// On Windows +readFileSync(new URL('file:///C:/p/a/t/h/%2F')); +readFileSync(new URL('file:///C:/p/a/t/h/%2f')); +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded +\ or / characters */ + +// On POSIX +readFileSync(new URL('file:///p/a/t/h/%2F')); +readFileSync(new URL('file:///p/a/t/h/%2f')); +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded +/ characters */ +``` + +On Windows, `file:` {URL}s having encoded backslash will result in an error: + +```js esm +import { readFileSync } from 'fs'; + +// On Windows +readFileSync(new URL('file:///C:/path/%5C')); +readFileSync(new URL('file:///C:/path/%5c')); +/* TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must not include encoded +\ or / characters */ +``` + +#### Buffer paths + +Paths specified using a {Buffer} are useful primarily on certain POSIX +operating systems that treat file paths as opaque byte sequences. On such +systems, it is possible for a single file path to contain sub-sequences that +use multiple character encodings. As with string paths, {Buffer} paths may +be relative or absolute: + +Example using an absolute path on POSIX: + +```js esm +import { open } from 'fs/promises'; + +let fd; +try { + fd = await open(Buffer.from('/open/some/file.txt'), 'r'); + // Do something with the file +} finally { + await fd.close(); +} +``` + +#### Per-drive working directories on Windows + +On Windows, Node.js follows the concept of per-drive working directory. This +behavior can be observed when using a drive path without a backslash. For +example `fs.readdirSync('C:\\')` can potentially return a different result than +`fs.readdirSync('C:')`. For more information, see +[this MSDN page][MSDN-Rel-Path]. + +### File descriptors + +On POSIX systems, for every process, the kernel maintains a table of currently +open files and resources. Each open file is assigned a simple numeric +identifier called a *file descriptor*. At the system-level, all file system +operations use these file descriptors to identify and track each specific +file. Windows systems use a different but conceptually similar mechanism for +tracking resources. To simplify things for users, Node.js abstracts away the +differences between operating systems and assigns all open files a numeric file +descriptor. + +The callback-based `fs.open()`, and synchronous `fs.openSync()` methods open a +file and allocate a new file descriptor. Once allocated, the file descriptor may +be used to read data from, write data to, or request information about the file. + +Operating systems limit the number of file descriptors that may be open +at any given time so it is critical to close the descriptor when operations +are completed. Failure to do so will result in a memory leak that will +eventually cause an application to crash. + +```js esm +import { open, close, fstat } from 'fs'; + +function closeFd(fd) { + close(fd, (err) => { + if (err) throw err; + }); +} + +open('/open/some/file.txt', 'r', (err, fd) => { + if (err) throw err; + try { + fstat(fd, (err, stat) => { + if (err) { + closeFd(fd); + throw err; + } + + // use stat + + closeFd(fd); + }); + } catch (err) { + closeFd(fd); + throw err; + } +}); +``` + +The promise-based APIs use a {FileHandle} object in place of the numeric +file descriptor. These objects are better managed by the system to ensure +that resources are not leaked. However, it is still required that they are +closed when operations are completed: + +```js esm +import { open } from 'fs/promises'; + +let file; +try { + file = await open('/open/some/file.txt', 'r'); + const stat = await file.stat(); + // use stat +} finally { + await file.close(); +} +``` + +### Threadpool usage + +All callback and promise-based file system APIs ( with the exception of +`fs.FSWatcher()`) use libuv's threadpool. This can have surprising and negative +performance implications for some applications. See the +[`UV_THREADPOOL_SIZE`][] documentation for more information. + +### File system flags The following flags are available wherever the `flag` option takes a string. @@ -6199,7 +6536,6 @@ the file contents. [#25741]: https://github.com/nodejs/node/issues/25741 [Caveats]: #fs_caveats [Common System Errors]: errors.md#errors_common_system_errors -[FS constants]: #fs_fs_constants_1 [File access constants]: #fs_file_access_constants [MDN-Date]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date [MDN-Number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type @@ -6210,20 +6546,12 @@ the file contents. [Writable Stream]: stream.md#stream_class_stream_writable [`AHAFS`]: https://www.ibm.com/developerworks/aix/library/au-aix_event_infrastructure/ [`Buffer.byteLength`]: buffer.md#buffer_static_method_buffer_bytelength_string_encoding -[`Buffer`]: buffer.md#buffer_buffer [`FSEvents`]: https://developer.apple.com/documentation/coreservices/file_system_events [`Number.MAX_SAFE_INTEGER`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER [`ReadDirectoryChangesW`]: https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-readdirectorychangesw -[`ReadStream`]: #fs_class_fs_readstream -[`URL`]: url.md#url_the_whatwg_url_api [`UV_THREADPOOL_SIZE`]: cli.md#cli_uv_threadpool_size_size -[`WriteStream`]: #fs_class_fs_writestream [`event ports`]: https://illumos.org/man/port_create [`filehandle.writeFile()`]: #fs_filehandle_writefile_data_options -[`fs.Dir`]: #fs_class_fs_dir -[`fs.Dirent`]: #fs_class_fs_dirent -[`fs.FSWatcher`]: #fs_class_fs_fswatcher -[`fs.Stats`]: #fs_class_fs_stats [`fs.access()`]: #fs_fs_access_path_mode_callback [`fs.chmod()`]: #fs_fs_chmod_path_mode_callback [`fs.chown()`]: #fs_fs_chown_path_uid_gid_callback @@ -6262,8 +6590,6 @@ the file contents. [`fsPromises.utimes()`]: #fs_fspromises_utimes_path_atime_mtime [`inotify(7)`]: https://man7.org/linux/man-pages/man7/inotify.7.html [`kqueue(2)`]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 -[`net.Socket`]: net.md#net_class_net_socket -[`stat()`]: fs.md#fs_fs_stat_path_options_callback [`util.promisify()`]: util.md#util_util_promisify_original [bigints]: https://tc39.github.io/proposal-bigint [chcp]: https://ss64.com/nt/chcp.html