9 C
New York
Wednesday, January 10, 2024

Learn how to use the File System in Node.js — SitePoint


Net purposes don’t all the time want to put in writing to the file system, however Node.js offers a complete utility programming interface (API) for doing so. It might be important in the event you’re outputting debugging logs, transferring information to or from a server, or creating command line instruments.

Studying and writing information from code isn’t essentially tough, however your utility will likely be extra strong in the event you do the next:

  1. Guarantee it’s cross-platform

    Home windows, macOS, and Linux deal with information otherwise. For instance, you utilize a ahead slash / to separate directories in macOS and Linux, however Home windows makes use of a backslash and bans sure file identify characters akin to : and ?.

  2. Double-check all the pieces!

    Customers or different apps may delete a file or change entry permissions. All the time examine for such points and deal with errors successfully.

Desk of Contents

The Node.js fs Module

The Node.js fs module offers strategies for managing information and directories. When you’re utilizing different JavaScript runtimes:

All JavaScript runtimes run on a single processing thread. The underlying working system handles operations akin to file studying and writing, so the JavaScript program continues to run in parallel. The OS then alerts the runtime when a file operation is full.

The fs documentation offers an extended checklist of capabilities, however there are three basic varieties with related capabilities, which we’ll take a look at subsequent.

1. Callback capabilities

These capabilities take a completion callback operate as an argument. The next instance passes an inline operate which outputs the content material of myfile.txt. Assuming no errors, its content material shows after finish of program seems within the console:

import { readFile } from 'node:fs';

readFile('myfile.txt', { encoding: 'utf8' }, (err, content material) => {
  if (!err) {
    console.log(content material);
  }
});

console.log('finish of program');

Observe: the { encoding: 'utf8' } parameter ensures Node.js returns a string of textual content content material slightly than a Buffer object of binary knowledge.

This turns into sophisticated when you have to run one after one other and descend into nested callback hell! It’s additionally simple to put in writing callback capabilities which look right however trigger reminiscence leaks which are tough to debug.

Typically, there’s little cause to make use of callbacks immediately. Few of the examples under use them.

2. Synchronous capabilities

The “Sync” capabilities successfully ignore Node’s non-blocking I/O and supply synchronous APIs such as you’d discover in different programming languages. The next instance outputs the content material of myfile.txt earlier than finish of program seems within the console:

import { readFileSync } from 'node:fs';

attempt {
  const content material = readFileSync('myfile.txt', { encoding: 'utf8' });
  console.log(content material);
}
catch {}

console.log('finish of program');

It seems to be simpler, and I’d by no means say don’t use Sync … however, erm … don’t use Sync! It halts the occasion loop and pauses your utility. That could be fantastic in a CLI program when loading a small initialization file, however think about a Node.js internet utility with 100 concurrent customers. If one consumer requests a file which takes one second to load, they wait one second for a response — and so do all the opposite 99 customers!

There’s no cause to make use of synchronous strategies when we’ve promise capabilities.

3. Promise capabilities

ES6/2015 launched guarantees. They’re syntactical sugar on callbacks to supply a sweeter, simpler syntax, particularly when used with async/await. Node.js additionally launched a ‘fs/guarantees’ API which seems to be and behaves in the same approach to the synchronous operate syntax however stays asynchronous:

import { readFile } from 'node:fs/guarantees';

attempt {
  const content material = await readFile('myfile.txt', { encoding: 'utf8' });
  console.log(content material);
}
catch {}

console.log('finish of program');

Observe using the 'node:fs/guarantees' module and the await earlier than readFile().

Most examples under use the promise-based syntax. Most don’t embrace attempt and catch for brevity, however it’s best to add these blocks to deal with errors.

ES module syntax

The examples on this tutorial additionally use ES Modules (ESM) import slightly than the CommonJS require. ESM is the usual module syntax supported by Deno, Bun, and browser runtimes.

To make use of ESM in Node.js, both:

  • identify your JavaScript information with a .mjs extension
  • use an --import=module change on the command line — akin to node --import=module index.js, or
  • if in case you have a challenge package deal.json file, add a brand new "kind": "module" setting

You possibly can nonetheless use CommonJS require ought to you have to.

Studying Recordsdata

There are a number of capabilities for studying information, however the easiest is to learn an entire file into reminiscence utilizing readFile, as we noticed within the instance above:

import { readFile } from 'node:fs/guarantees';
const content material = await readFile('myfile.txt', { encoding: 'utf8' });

The second choices object will also be a string. It defines the encoding: set 'utf8' or one other textual content format to learn the file content material right into a string.

Alternatively, you possibly can learn traces one after the other utilizing the readLines() technique of the filehandle object:

import { open } from 'node:fs/guarantees';

const file = await open('myfile.txt');

for await (const line of file.readLines()) {
  console.log(line);
}

There are additionally extra superior choices for studying streams or any variety of bytes from a file.

Dealing with File and Listing Paths

You’ll usually need to entry information at particular absolute paths or paths relative to the Node utility’s working listing. The node:path module offers cross-platform strategies to resolve paths on all working techniques.

The path.sep property returns the listing separator image — on Home windows or / on Linux or macOS:

import * as path from 'node:path';

console.log( path.sep );

However there are extra helpful properties and capabilities. be a part of([…paths]) joins all path segments and normalizes for the OS:

console.log( path.be a part of('/challenge', 'node/example1', '../example2', 'myfile.txt') );

resolve([…paths]) is comparable however returns the complete absolute path:

console.log( path.resolve('/challenge', 'node/example1', '../example2', 'myfile.txt') );

normalize(path) resolves all listing .. and . references:

console.log( path.normalize('/challenge/node/example1/../example2/myfile.txt') );

relative(from, to) calculates the relative path between two absolute or relative paths (based mostly on Node’s working listing):

console.log( path.relative('/challenge/node/example1', '/challenge/node/example2') );

format(object) builds a full path from an object of constituent elements:

console.log(
  path.format({
    dir: '/challenge/node/example2',
    identify: 'myfile',
    ext: 'txt'
  })
);

parse(path) does the other and returns an object describing a path:

console.log( path.parse('/challenge/node/example2/myfile.txt') );

Getting File and Listing Data

You usually must get details about a path. Is it a file? Is it a listing? When was it created? When was it final modified? Are you able to learn it? Are you able to append knowledge to it?

The stat(path) operate returns a Stats object containing details about a file or listing object:

import { stat } from 'node:fs/guarantees';

const data = await stat('myfile.txt');
console.log(data);

It additionally offers helpful strategies, together with:

const isFile = data.isFile(); 
const isDirectory = data.isDirectory(); 

The entry(path) operate exams whether or not a file could be accessed utilizing a selected mode set by way of a fixed. If the accessibility examine is profitable, the promise fulfills with no worth. A failure rejects the promise. For instance:

import { entry, constants } from 'node:fs/guarantees';

const data = {
  canRead: false,
  canWrite: false,
  canExec: false
};


attempt {
  await entry('myfile.txt', constants.R_OK);
  data.canRead = true;
}
catch {}


attempt {
  await entry('myfile.txt', constants.W_OK);
  data.canWrite = true;
}
catch {}

console.log(data);

You possibly can take a look at multiple mode, akin to whether or not a file is each readable and writeable:

await entry('myfile.txt', constants.R_OK | constants.W_OK);

Writing Recordsdata

writeFile() is the best operate to asynchronously write an entire file changing its content material if it already exists:

import { writeFile } from 'node:fs/guarantees';
await writeFile('myfile.txt', 'new file contents');

Go the next arguments:

  1. the file path
  2. the file content material — generally is a String, Buffer, TypedArray, DataView, Iterable, or Stream
  3. an non-obligatory third argument generally is a string representing the encoding (akin to 'utf8') or an object with properties akin to encoding and sign to abort the promise.

An identical appendFile() operate provides new content material to the top of the present file, creating that file if it doesn’t exist.

For the adventurous, there’s a file handler write() technique which lets you substitute content material inside a file at a selected level and size.

Creating Directories

The mkdir() operate can create full listing constructions by passing an absolute or relative path:

import { mkdir } from 'node:fs/guarantees';

await mkdir('./subdir/temp', { recursive: true });

You possibly can cross two arguments:

  1. the listing path, and
  2. an non-obligatory object with a recursive Boolean and mode string or integer

Setting recursive to true creates the entire listing construction. The instance above creates subdir within the present working listing and temp as a subdirectory of that. If recursive had been false (the default) the promise would reject if subdir weren’t already outlined.

The mode is the macOS/Linux consumer, group, and others permission with a default of 0x777. This isn’t supported on Home windows and ignored.

The same .mkdtemp() operate is comparable and creates a singular listing sometimes for non permanent knowledge storage.

Studying Listing Contents

.readdir() reads the content material of a listing. The promise fulfills with an array containing all file and listing names (apart from . and ..). The identify is relative to the listing and doesn’t embrace the complete path:

import { readdir } from 'node:fs/guarantees';

const information = await readdir('./'); 
for (const file of information) {
  console.log(file);
}


You possibly can cross an non-obligatory second parameter object with the next properties:

  • encoding — the default is an array of utf8 strings
  • recursive — set true to recursively fetch all information from all subdirectories. The file identify will embrace the subdirectory identify(s). Older editions of Node.js might not present this feature.
  • withFileType — set true to return an array of fs.Dirent objects which incorporates properties and strategies together with .identify, .path, .isFile(), .isDirectory() and extra.

The choice .opendir() operate lets you asynchronously open a listing for iterative scanning:

import { opendir } from 'node:fs/guarantees';

const dir = await opendir('./');
for await (const entry of dir) {
  console.log(entry.identify);
}

Deleting Recordsdata and Directories

The .rm() operate removes a file or listing at a specified path:

import { rm } from 'node:fs/guarantees';

await rm('./oldfile.txt');

You possibly can cross an non-obligatory second parameter object with the next properties:

  • pressure — set true to not increase an error when the trail doesn’t exist
  • recursive — set true to recursively delete a listing and contents
  • maxRetries — make various retries when one other course of has locked a file
  • retryDelay — the variety of milliseconds between retries

The same .rmdir() operate solely deletes directories (you possibly can’t cross a file path). Equally, .unlink() solely deletes information or symbolic hyperlinks (you possibly can’t cross a listing path).

Different File System Capabilities

The examples above illustrate the most-used choices for studying, writing, updating, and deleting information and directories. Node.js additionally offers additional, lesser-used choices akin to copying, renaming, altering possession, altering permissions, altering date properties, creating symbolic hyperlinks, and waiting for file modifications.

It might be preferable to make use of the callback-based API when waiting for file modifications, as a result of it’s much less code, simpler to make use of, and might’t halt different processes:

import { watch } from 'node:fs';


watch('./mydir', { recursive: true }, (occasion, file) => {

  console.log(`occasion: ${ occasion }`);

  if (file) {
    console.log(`file modified: ${ file }`);
  }

});


The occasion parameter acquired by the callback is both 'change' or 'rename'.

Abstract

Node.js offers a versatile and cross-platform API to handle information and directories on any working system the place you should use the runtime. With a little bit care, you possibly can write strong and moveable JavaScript code that may work together with any file system.

For extra data, consult with the Node.js fs and path documentation. Different helpful libraries embrace:

  • OS to question working oystem data
  • URL to parse a URL, maybe when mapping to and from file system paths
  • Stream for dealing with giant information
  • Buffer and TypedArray objects to deal with binary knowledge
  • Youngster processes to spawn a subprocess to deal with long-running or complicated file manipulation capabilities.

You may as well discover higher-level file system modules on npm, however there’s no higher expertise than writing your personal.

FAQs on Accessing the File System in Node.js

What’s the File System module in Node.js?

The File System module, also known as fs, is a core module in Node.js that gives strategies and performance for interacting with the file system, together with studying and writing information.

How can I embrace the fs module in a Node.js script?

You possibly can embrace the fs module by utilizing the require assertion, like this: const fs = require('fs');. This makes all fs strategies out there in your script.

What’s the distinction between synchronous and asynchronous file operations in Node.js?

Synchronous file operations block the Node.js occasion loop till the operation is accomplished, whereas asynchronous operations don’t block the occasion loop, permitting your utility to stay responsive. Asynchronous operations are sometimes really helpful for I/O duties.

How do I learn the contents of a file in Node.js utilizing the fs module?

You should use the fs.readFile() technique to learn the contents of a file. Present the file path and a callback operate to deal with the info as soon as it’s learn.

What’s the function of the callback operate when working with the fs module in Node.js?

Callback capabilities in fs operations are used to deal with the results of asynchronous file operations. They’re referred to as when the operation is full, passing any errors and knowledge as arguments.

How can I examine if a file exists in Node.js utilizing the fs module?

You should use the fs.existsSync() technique to examine if a file exists at a specified path. It returns true if the file exists and false if it doesn’t.

What’s the fs.createReadStream() technique, and when is it helpful?

fs.createReadStream() is used for studying giant information effectively. It creates a readable stream for the required file, permitting you to learn and course of knowledge in smaller, manageable chunks.

Can I take advantage of the fs module to create and write to a brand new file in Node.js?

Sure, you should use the fs.writeFile() or fs.createWriteStream() strategies to create and write to a brand new file. These strategies permit you to specify the file path, content material, and choices for writing.

How do I deal with errors when working with the fs module in Node.js?

It is best to all the time deal with errors by checking the error parameter within the callback operate offered to asynchronous fs strategies or by utilizing attempt/catch blocks for synchronous operations.

Is it attainable to delete a file utilizing the fs module in Node.js?

Sure, you should use the fs.unlink() technique to delete a file. Present the file path and a callback operate to deal with the end result.

Can I take advantage of the fs module to work with directories and folder constructions in Node.js?

Sure, the fs module offers strategies to create, learn, and manipulate directories, together with creating directories, itemizing their contents, and eradicating directories.



Supply hyperlink

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles