Skip to main content

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.

Next Steps​