Node.js File System, Learn everything!
The fs
module is a built-in Node.js module that allows interaction with the file system. It enables you to:
Create, read, write, and delete files and directories.
Manage file metadata.
Work with both synchronous and asynchronous operations.
1. Node.js fs
Module Asynchronous/Synchronous Methods:
Asynchronous Methods:
Non-blocking (do not pause the execution of the program).
Use callbacks or promises to handle results.
Preferred for real-world applications to avoid blocking the event loop.
Synchronous Methods:
Blocking (execution halts until the operation completes).
Easier to understand but can degrade performance in large-scale applications.
Best for scripts or initialization tasks.
2. Difference Between Asynchronous and Synchronous Methods
Here’s an example that demonstrates the difference:
Asynchronous Example
const fs = require('fs');
console.log('Start');
fs.writeFile('example-async.txt', 'Hello, Async World!', (err) => {
if (err) throw err;
console.log('File created asynchronously');
});
console.log('End');
Output:
Start
End
File created asynchronously
Synchronous Example
const fs = require('fs');
console.log('Start');
fs.writeFileSync('example-sync.txt', 'Hello, Sync World!');
console.log('File created synchronously');
console.log('End');
Output:
Start
File created synchronously
End
Key Differences
Feature | Asynchronous | Synchronous |
Execution | Non-blocking | Blocking |
Performance | Better for large-scale operations | Slows down the program |
Error Handling | Via callback or promises | Uses try-catch |
Use Case | Real-time apps, servers | Initialization scripts, small tasks |
3. Core Operations: Create, Read, Append, Delete
We’ll go through each file system operation using both asynchronous and synchronous methods. Explanation accompanies every step.
3.1. Creating a Folder
Asynchronous
const fs = require('fs');
const path = require('path');
const folderPath = path.join(__dirname, 'myFolder');
// Create folder asynchronously
fs.mkdir(folderPath, { recursive: true }, (err) => {
if (err) throw err;
console.log('Folder created asynchronously!');
});
Synchronous
const fs = require('fs');
const path = require('path');
const folderPath = path.join(__dirname, 'myFolder');
// Create folder synchronously
fs.mkdirSync(folderPath, { recursive: true });
console.log('Folder created synchronously!');
3.2. Creating a File
Asynchronous
const filePath = path.join(folderPath, 'example.txt');
const content = 'Hello, this is a sample file content.';
// Create file asynchronously
fs.writeFile(filePath, content, (err) => {
if (err) throw err;
console.log('File created asynchronously!');
});
Synchronous
const filePath = path.join(folderPath, 'example.txt');
const content = 'Hello, this is a sample file content.';
// Create file synchronously
fs.writeFileSync(filePath, content);
console.log('File created synchronously!');
3.3. Reading a File
Asynchronous
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) throw err;
console.log('File content (Async):', data);
});
Synchronous
const data = fs.readFileSync(filePath, 'utf8');
console.log('File content (Sync):', data);
3.4. Appending to a File
Asynchronous
const additionalContent = '\nThis is some appended content.';
// Append to file asynchronously
fs.appendFile(filePath, additionalContent, (err) => {
if (err) throw err;
console.log('Content appended asynchronously!');
});
Synchronous
const additionalContent = '\nThis is some appended content.';
// Append to file synchronously
fs.appendFileSync(filePath, additionalContent);
console.log('Content appended synchronously!');
3.5. Deleting a File
Asynchronous
fs.unlink(filePath, (err) => {
if (err) throw err;
console.log('File deleted asynchronously!');
});
Synchronous
fs.unlinkSync(filePath);
console.log('File deleted synchronously!');
3.6. Deleting a Folder
Asynchronous
fs.rmdir(folderPath, { recursive: true }, (err) => {
if (err) throw err;
console.log('Folder deleted asynchronously!');
});
Synchronous
fs.rmdirSync(folderPath, { recursive: true });
console.log('Folder deleted synchronously!');
4. Error Handling
Error handling ensures your app doesn’t crash unexpectedly. Always handle errors when performing file system operations.
Example with Asynchronous Operations
fs.readFile('nonexistent.txt', 'utf8', (err, data) => {
if (err) {
if (err.code === 'ENOENT') {
console.error('File not found!');
} else {
throw err;
}
return;
}
console.log(data);
});
Example with Synchronous Operations
try {
const data = fs.readFileSync('nonexistent.txt', 'utf8');
console.log(data);
} catch (err) {
if (err.code === 'ENOENT') {
console.error('File not found!');
} else {
throw err;
}
}
5. Practical Example: Complete Workflow
Let’s combine everything into a single workflow:
Create a folder.
Create a file inside it.
Read the file content.
Append more content.
Delete the file.
Delete the folder.
javascriptCopy codeconst folderPath = path.join(__dirname, 'myFolder');
const filePath = path.join(folderPath, 'example.txt');
// Create folder
fs.mkdir(folderPath, { recursive: true }, (err) => {
if (err) throw err;
console.log('Folder created.');
// Create file
fs.writeFile(filePath, 'Hello, World!', (err) => {
if (err) throw err;
console.log('File created.');
// Read file
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) throw err;
console.log('File content:', data);
// Append content
fs.appendFile(filePath, '\nAppended Content!', (err) => {
if (err) throw err;
console.log('Content appended.');
// Delete file
fs.unlink(filePath, (err) => {
if (err) throw err;
console.log('File deleted.');
// Delete folder
fs.rmdir(folderPath, { recursive: true }, (err) => {
if (err) throw err;
console.log('Folder deleted.');
});
});
});
});
});
});
6. Best Practices
Use asynchronous methods for non-blocking operations.
Prefer promises or async/await for cleaner asynchronous code.
Always handle errors gracefully.
Use
path
module for constructing cross-platform paths.
Subscribe to my newsletter
Read articles from Asawer directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by