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