In node, the fs module refers to the "file system module", which is a module used to operate files. Most APIs of the fs module provide three operating methods: 1. Synchronous file operation: the code will be blocked and will not continue to execute; 2. Asynchronous callback function operation file: the code will not be blocked and a callback function needs to be passed in. When the When the result is generated, the callback function is executed; 3. Asynchronous Promise operation file: the code will not be blocked, and a Promise will be returned by calling the method operation through fs.promises.
The operating environment of this tutorial: Windows 7 system, nodejs version 16, DELL G3 computer.
The file system module (fs for short) allows us to access and interact with the file system on our computer.
The fs module is a module officially provided by Node.js for operating files. It provides a series of methods and properties to meet users' file operation needs.
fs.readFile() method, used to read the contents of the specified file
fs.writeFile() method, used to write content to the specified file if you want to use it in JavaScript code
The filesystem module is a core Node.js module. This means we don't have to install it. The only thing we need to do is import the fs module into its own file.
So at the top of the file add:
const fs = require('fs')Now we can call any method from file system module using prefix fs.
Alternatively, we can just import the required methods from the fs API as follows:
const { writeFile, readFile } = require('fs')Note: For convenience, we also need to import the path module. It is another core Node.js module that allows us to work with file and directory paths.
After importing the fs module, add:
const path = require('path')When using the filesystem module, the path module is not required. But it helps us a lot!
File operations of the fs module generally support two APIs: synchronous and asynchronous. Asynchronous also includes callback functions and promsie forms. Synchronization is usually followed by the word sync.
Most APIs of the fs module provide three operation methods:
Synchronous operation of files: the code will be blocked and will not continue to execute
Asynchronous callback function operation file: the code will not be blocked, the callback function needs to be passed in, and when the result is obtained, the callback function is executed
Asynchronous Promise operation files: The code will not be blocked. Calling method operations through fs.promises will return a Promise, which can be processed through then and catch.
Note that all fs methods are asynchronous by default. However, we can use the synchronized version by adding Sync at the end of the method.
For example, the synchronous version of the writeFile method is writeFileSync. Synchronous methods complete code synchronously, so they block the main thread. Blocking the main thread in Node.js is considered bad practice and we shouldn't do it.
Therefore, below we will use the asynchronous methods in the file system module.
To write to a file from a Node.js application, use the writeFile method.
The writeFile method accepts at least the following parameters:
File name content callbackIf the specified file already exists, it replaces the old content with the content you provide as argument. If the specified file does not exist, a new file is created.
After importing the fs and path modules, write the following code in the file:
fs.writeFile('content.txt', 'All work and no play makes Jack a dull boy!', err => { if (err) throw err process.stdout.write('Created successfully!')})The above code will create a new file named content.txt and add the text All work and no play makes Jack a dull boy! as the content. If there are any errors, the callback function will throw that error. Otherwise, it will output to the console that the file was created successfully.
There are other variations of writeFile, such as:
fs.writeFileSync — Write files synchronously fsPromises.writeFile — Write files using Promise-based APICheck out this gist: https://gist.github.com/catalinpit/571ba06c06214b5c8744036c6500af92
Before reading a file, the path to the file needs to be created and stored. The path module's path is convenient here.
Using the path method from the join module, you can create a file path as follows:
const filePath = path.join(process.cwd(), 'content.txt')The first parameter process.cwd() returns the current working directory. Now that you have the file path, you can read the file's contents.
Write the following code in the file:
fs.readFile(filePath, (error, content) => { if (error) throw error process.stdout.write(content)})The readFile method accepts at least two parameters:
File path callbackIf there is an error, it will throw an error. Otherwise, it prints the file contents in the terminal.
There are other variations of readFile, such as:
fs.readFileSync — Write to a file synchronously fsPromises.readFile — Write to a file using a Promise-based APICheck out this gist: https://gist.github.com/catalinpit/badc2a539a44412892a0e05a9575d54d
Displaying a file in a directory is very similar to reading the file contents. However, instead of passing the file path, pass the current working directory (we can pass any other directory).
Then, pass a callback function to handle the response. Write the following code in the file:
fs.readdir(process.cwd(), (error, files) => { if (error) throw error console.log(files)})So far, we've only used process.stdout.write to output content to the terminal. However, you can simply use console.log, like in the code snippet above.
If we run the application, we should get an array containing all the files in the directory.
Check out this gist: https://gist.github.com/catalinpit/f82c4e6ae3acd5d97efdecb0bc67979e
The filesystem module has a method that allows you to delete files. However, it's important to note that it only works for files, not directories.
When the unlink method is called with a file path as parameter, it deletes the file. Add the following code snippet to the file:
fs.unlink(filePath, error => { if (error) throw error console.log('File has been deleted!')})If you rerun the code, your files will be deleted!
Check out this gist: https://gist.github.com/catalinpit/b1201434218c400f77e042109bfce99e
We can create a directory asynchronously using the mkdir method. Write the following code in the file:
fs.mkdir(`${process.cwd()}/myFolder/secondFolder`, { recursive: true }, (err) => { if (err) throw err console.log('Folder created successfully!') })First, create a new folder in the current working directory. As mentioned before, you can get the current working directory from the process object using the cwd() method.
Then, pass the folder or folders to be created. However, this doesn't mean you have to create a new folder in your current working directory. You can create them anywhere.
Now, the second parameter is the recursive option. If it is not set to true, multiple folders cannot be created. If the recursive option is set to false, the above code will give an error. Give it a try!
However, if you only want to create a folder, there is no need to set the recursive option to true.
The following code works fine!
fs.mkdir(`${process.cwd()}/myFolder`, err => { if (err) throw err console.log('Folder created successfully!')});Therefore, I would like to emphasize the use of recursive. You need to set this to true if you want to create folders within folders. It will create all folders even if they don't exist.
On the other hand, if you only want to create a folder, you can leave it false.
Check out this gist: https://gist.github.com/catalinpit/09bad802541102c0cce2a2e4c3985066
The logic for deleting a directory is similar to creating a directory. If you look at the code written to create the directory and the code below, you will see similarities.
So write the following code in the file:
fs.rmdir(`${process.cwd()}/myFolder/`, { recursive: true }, err => { if (err) throw err console.log('Folder deleted successfully!')})Use the rmdir method from the filesystem module and pass the following parameters:
Directory to be deleted recursive property callbackIf the recursive property is set to true, it deletes the folder and its contents. It's important to note that you need to set this to true if the folder contains content. Otherwise you will get an error.
The following code snippet only works when the folder is empty:
fs.rmdir(`${process.cwd()}/myFolder/`, err => { if (err) throw err console.log('Folder deleted successfully!')})If there are other files and/or folders in myFolder, an error will occur if { recursive: true } is not passed.
It's important to know when to use the recursive option and when not to avoid problems.
Check out this gist: https://gist.github.com/catalinpit/a8cb6aca75cef8d6ac5043eae9ba22ce
Using the fs module, you can rename directories and files. The following code snippet shows how to do this using the rename method.
// Rename a directory fs.rename(`${process.cwd()}/myFolder/secondFolder`, `${process.cwd()}/myFolder/newFolder`, err => { if (err) throw err console.log('Directory rename!')});//Rename a file fs.rename(`${process.cwd()}/content.txt`, `${process.cwd()}/newFile .txt`, err => { if (err) throw err console.log('File renamed!')});The rename method contains three parameters:
The first parameter is the existing folder/file and the second parameter is the new name callbackSo, to rename a file or directory, we need to pass the name of the current file/directory and the new name. After running the application, the names of the directories/files should be updated.
Note that if the new path already exists (for example, a new name for a file/folder), it will be overwritten. So make sure not to overwrite existing files/folders by mistake.
Check out this gist: https://gist.github.com/catalinpit/5c3e7c6ae39d09996ff67175a719122e
We can also add new content to an existing file using the appendFile method.
If we compare the two methods writeFile and appendFile, we can see that they are similar. Pass the file path, content and callback.
fs.appendFile(filePath, 'nAll work and no play makes Jack a dull boy!', err => { if (err) throw err console.log('All work and no play makes Jack a dull boy!')} )The code snippet above demonstrates how to add new content to an existing file. If you run the application and open the file, you should see the new content inside.