Chapter 3: File System Operations
Node.js provides powerful file system operation capabilities through the fs
module, allowing you to read, write, delete files, and manipulate directories.
Learning Objectives
Through this chapter, you will master:
- File reading and writing operations
- Synchronous and asynchronous file operations
- Directory operations
- File watching
- Streaming file operations
File Reading
Synchronous Reading
const fs = require('fs');
try {
const data = fs.readFileSync('file.txt', 'utf8');
console.log(data);
} catch (err) {
console.error('Error reading file:', err);
}
Asynchronous Reading
const fs = require('fs');
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) {
console.error('Error reading file:', err);
return;
}
console.log(data);
});
Promise-based Reading
const fs = require('fs').promises;
async function readFile() {
try {
const data = await fs.readFile('file.txt', 'utf8');
console.log(data);
} catch (err) {
console.error('Error reading file:', err);
}
}
readFile();
File Writing
Synchronous Writing
const fs = require('fs');
try {
fs.writeFileSync('output.txt', 'Hello, Node.js!', 'utf8');
console.log('File written successfully');
} catch (err) {
console.error('Error writing file:', err);
}
Asynchronous Writing
const fs = require('fs');
fs.writeFile('output.txt', 'Hello, Node.js!', 'utf8', (err) => {
if (err) {
console.error('Error writing file:', err);
return;
}
console.log('File written successfully');
});
Append Writing
const fs = require('fs');
fs.appendFile('log.txt', 'New log entry\n', 'utf8', (err) => {
if (err) {
console.error('Error appending file:', err);
return;
}
console.log('Log appended successfully');
});
Directory Operations
Create Directory
const fs = require('fs');
// Create single directory
fs.mkdir('newDir', (err) => {
if (err) {
console.error('Error creating directory:', err);
return;
}
console.log('Directory created successfully');
});
// Create nested directories
fs.mkdir('path/to/nested/dir', { recursive: true }, (err) => {
if (err) {
console.error('Error creating directory:', err);
return;
}
console.log('Nested directories created successfully');
});
Read Directory
const fs = require('fs');
fs.readdir('.', (err, files) => {
if (err) {
console.error('Error reading directory:', err);
return;
}
console.log('Directory contents:', files);
});
Remove Directory
const fs = require('fs');
fs.rmdir('emptyDir', (err) => {
if (err) {
console.error('Error removing directory:', err);
return;
}
console.log('Directory removed successfully');
});
File Information
const fs = require('fs');
fs.stat('file.txt', (err, stats) => {
if (err) {
console.error('Error getting file info:', err);
return;
}
console.log('File size:', stats.size);
console.log('Created time:', stats.birthtime);
console.log('Modified time:', stats.mtime);
console.log('Is file:', stats.isFile());
console.log('Is directory:', stats.isDirectory());
});
File Watching
const fs = require('fs');
// Watch file changes
fs.watchFile('file.txt', (curr, prev) => {
console.log('File has been modified');
console.log('Current time:', curr.mtime);
console.log('Previous time:', prev.mtime);
});
// Stop watching
fs.unwatchFile('file.txt');
Streaming File Operations
Read Stream
const fs = require('fs');
const readStream = fs.createReadStream('large-file.txt', 'utf8');
readStream.on('data', (chunk) => {
console.log('Read data chunk:', chunk.length);
});
readStream.on('end', () => {
console.log('File reading completed');
});
readStream.on('error', (err) => {
console.error('Read error:', err);
});
Write Stream
const fs = require('fs');
const writeStream = fs.createWriteStream('output.txt');
writeStream.write('First line of data\n');
writeStream.write('Second line of data\n');
writeStream.end('Last line of data\n');
writeStream.on('finish', () => {
console.log('File writing completed');
});
writeStream.on('error', (err) => {
console.error('Write error:', err);
});
Practice Project: File Manager
Create a simple file manager:
const fs = require('fs');
const path = require('path');
class FileManager {
constructor(basePath) {
this.basePath = basePath;
}
// List directory contents
listDir(dirPath = '.') {
return new Promise((resolve, reject) => {
const fullPath = path.join(this.basePath, dirPath);
fs.readdir(fullPath, (err, files) => {
if (err) {
reject(err);
return;
}
resolve(files);
});
});
}
// Create file
createFile(filePath, content) {
return new Promise((resolve, reject) => {
const fullPath = path.join(this.basePath, filePath);
fs.writeFile(fullPath, content, 'utf8', (err) => {
if (err) {
reject(err);
return;
}
resolve('File created successfully');
});
});
}
// Read file
readFile(filePath) {
return new Promise((resolve, reject) => {
const fullPath = path.join(this.basePath, filePath);
fs.readFile(fullPath, 'utf8', (err, data) => {
if (err) {
reject(err);
return;
}
resolve(data);
});
});
}
}
// Usage example
const fileManager = new FileManager('./');
fileManager.listDir()
.then(files => console.log('Directory contents:', files))
.catch(err => console.error('Error:', err));
Summary
This chapter introduced Node.js file system operations, including:
- File reading, writing, and deletion
- Directory creation, reading, and deletion
- File information retrieval
- File watching
- Streaming file operations
Mastering file system operations is an important skill in Node.js development, providing the foundation for building file processing applications.