Working with file descriptors in Node.js
Before you're able to interact with a file that sits in your filesystem, you must get a file descriptor.
A file descriptor is a reference to an open file, a number (fd) returned by opening the file using the open()
method offered by the fs
module. This number (fd
) uniquely identifies an open file in operating system:
const module "node:fs"
fs = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('node:fs');
module "node:fs"
fs.function open(path: fs.PathLike, flags: fs.OpenMode | undefined, callback: (err: NodeJS.ErrnoException | null, fd: number) => void): void (+2 overloads)
Asynchronous open(2) - open and possibly create a file. If the file is created, its mode will be `0o666`.open('/Users/joe/test.txt', 'r', (err: NodeJS.ErrnoException | null
err, fd: number
fd) => {
// fd is our file descriptor
});
Notice the r
we used as the second parameter to the fs.open()
call.
That flag means we open the file for reading.
Other flags you'll commonly use are:
Flag | Description | File gets created if it doesn't exist |
---|---|---|
r+ | This flag opens the file for reading and writing | ❌ |
w+ | This flag opens the file for reading and writing and it also positions the stream at the beginning of the file | ✅ |
a | This flag opens the file for writing and it also positions the stream at the end of the file | ✅ |
a+ | This flag opens the file for reading and writing and it also positions the stream at the end of the file | ✅ |
You can also open the file by using the fs.openSync
method, which returns the file descriptor, instead of providing it in a callback:
const module "node:fs"
fs = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('node:fs');
try {
const const fd: number
fd = module "node:fs"
fs.function openSync(path: fs.PathLike, flags: fs.OpenMode, mode?: fs.Mode | null): number
Returns an integer representing the file descriptor.
For detailed information, see the documentation of the asynchronous version of
this API:
{@link
open
}
.openSync('/Users/joe/test.txt', 'r');
} catch (var err: unknown
err) {
var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.error(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stderr` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const code = 5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
```
If formatting elements (e.g. `%d`) are not found in the first string then
[`util.inspect()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilinspectobject-options) is called on each argument and the
resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)
for more information.error(var err: unknown
err);
}
Once you get the file descriptor, in whatever way you choose, you can perform all the operations that require it, like calling fs.close()
and many other operations that interact with the filesystem.
You can also open the file by using the promise-based fsPromises.open
method offered by the fs/promises
module.
The fs/promises
module is available starting only from Node.js v14. Before v14, after v10, you can use require('fs').promises
instead. Before v10, after v8, you can use util.promisify
to convert fs
methods into promise-based methods.
const module "node:fs/promises"
fs = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('node:fs/promises');
// Or const fs = require('fs').promises before v14.
async function function example(): Promise<void>
example() {
let let filehandle: any
filehandle;
try {
let filehandle: any
filehandle = await module "node:fs/promises"
fs.function open(path: PathLike, flags?: string | number, mode?: Mode): Promise<fs.FileHandle>
Opens a `FileHandle`.
Refer to the POSIX [`open(2)`](http://man7.org/linux/man-pages/man2/open.2.html) documentation for more detail.
Some characters (`< > : " / \ | ? *`) are reserved under Windows as documented
by [Naming Files, Paths, and Namespaces](https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file). Under NTFS, if the filename contains
a colon, Node.js will open a file system stream, as described by [this MSDN page](https://docs.microsoft.com/en-us/windows/desktop/FileIO/using-streams).open('/Users/joe/test.txt', 'r');
var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.log(let filehandle: fs.FileHandle
filehandle.FileHandle.fd: number
The numeric file descriptor managed by the {FileHandle} object.fd);
var console: Console
The `console` module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
* A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
_**Warning**_: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
```
Example using the `Console` class:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
```console.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.log(await let filehandle: fs.FileHandle
filehandle.FileHandle.readFile(options: ({
encoding: BufferEncoding;
} & EventEmitter<T extends EventMap<T> = DefaultEventMap>.Abortable) | BufferEncoding): Promise<string> (+2 overloads)
Asynchronously reads the entire contents of a file. The underlying file will _not_ be closed automatically.
The `FileHandle` must have been opened for reading.readFile({ encoding: BufferEncoding
encoding: 'utf8' }));
} finally {
if (let filehandle: fs.FileHandle | undefined
filehandle) {
await let filehandle: fs.FileHandle
filehandle.FileHandle.close(): Promise<void>
Closes the file handle after waiting for any pending operation on the handle to
complete.
```js
import { open } from 'node:fs/promises';
let filehandle;
try {
filehandle = await open('thefile.txt', 'r');
} finally {
await filehandle?.close();
}
```close();
}
}
}
function example(): Promise<void>
example();
Here is an example of util.promisify
:
const module "node:fs"
fs = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('node:fs');
const module "node:util"
util = var require: NodeJS.Require
(id: string) => any
Used to import modules, `JSON`, and local files.require('node:util');
async function function example(): Promise<void>
example() {
const const open: (path: fs.PathLike, flags: fs.OpenMode, mode?: fs.Mode | null) => Promise<number>
open = module "node:util"
util.function promisify<(path: fs.PathLike, flags: fs.OpenMode, mode?: fs.Mode | null) => Promise<number>>(fn: util.CustomPromisify<(path: fs.PathLike, flags: fs.OpenMode, mode?: fs.Mode | null) => Promise<number>>): (path: fs.PathLike, flags: fs.OpenMode, mode?: fs.Mode | null) => Promise<number> (+13 overloads)
Takes a function following the common error-first callback style, i.e. taking
an `(err, value) => ...` callback as the last argument, and returns a version
that returns promises.
```js
import { promisify } from 'node:util';
import { stat } from 'node:fs';
const promisifiedStat = promisify(stat);
promisifiedStat('.').then((stats) => {
// Do something with `stats`
}).catch((error) => {
// Handle the error.
});
```
Or, equivalently using `async function`s:
```js
import { promisify } from 'node:util';
import { stat } from 'node:fs';
const promisifiedStat = promisify(stat);
async function callStat() {
const stats = await promisifiedStat('.');
console.log(`This directory is owned by ${stats.uid}`);
}
callStat();
```
If there is an `original[util.promisify.custom]` property present, `promisify`
will return its value, see [Custom promisified functions](https://nodejs.org/docs/latest-v22.x/api/util.html#custom-promisified-functions).
`promisify()` assumes that `original` is a function taking a callback as its
final argument in all cases. If `original` is not a function, `promisify()`
will throw an error. If `original` is a function but its last argument is not
an error-first callback, it will still be passed an error-first
callback as its last argument.
Using `promisify()` on class methods or other methods that use `this` may not
work as expected unless handled specially:
```js
import { promisify } from 'node:util';
class Foo {
constructor() {
this.a = 42;
}
bar(callback) {
callback(null, this.a);
}
}
const foo = new Foo();
const naiveBar = promisify(foo.bar);
// TypeError: Cannot read properties of undefined (reading 'a')
// naiveBar().then(a => console.log(a));
naiveBar.call(foo).then((a) => console.log(a)); // '42'
const bindBar = naiveBar.bind(foo);
bindBar().then((a) => console.log(a)); // '42'
```promisify(module "node:fs"
fs.function open(path: fs.PathLike, flags: fs.OpenMode | undefined, mode: fs.Mode | undefined | null, callback: (err: NodeJS.ErrnoException | null, fd: number) => void): void (+2 overloads)
Asynchronous file open. See the POSIX [`open(2)`](http://man7.org/linux/man-pages/man2/open.2.html) documentation for more details.
`mode` sets the file mode (permission and sticky bits), but only if the file was
created. On Windows, only the write permission can be manipulated; see
{@link
chmod
}
.
The callback gets two arguments `(err, fd)`.
Some characters (`< > : " / \ | ? *`) are reserved under Windows as documented
by [Naming Files, Paths, and Namespaces](https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file). Under NTFS, if the filename contains
a colon, Node.js will open a file system stream, as described by [this MSDN page](https://docs.microsoft.com/en-us/windows/desktop/FileIO/using-streams).
Functions based on `fs.open()` exhibit this behavior as well:`fs.writeFile()`, `fs.readFile()`, etc.open);
const const fd: number
fd = await const open: (path: fs.PathLike, flags: fs.OpenMode, mode?: fs.Mode | null) => Promise<number>
Asynchronous open(2) - open and possibly create a file.open('/Users/joe/test.txt', 'r');
}
function example(): Promise<void>
example();
To see more details about the fs/promises
module, please check fs/promises API.