File System fs Module — Biryani Menu File Read Karna
The fs module lets you interact with the file system — read, write, update, delete, and watch files.
The fs (file system) module is a built-in Node.js module that lets you work with files and directories on your computer. It comes with Node.js — no installation needed.
Think of it as your chai tapri kitchen storage:
- Reading files = Menu card padhna (biryani types, prices check karna)
- Writing files = Naya menu likhna (prices update karna)
- Creating directories = Naya storage rack rakhna (chai patti, sugar ke liye)
- Watching files = Chef ko dekhna jab bhi menu badalta hai
- Deleting files= Purana menu hatana (seasonal items hatao)
The fs module has three APIs for almost every operation:
| API Style | Example | Best For |
|---|---|---|
| Callback (async) | fs.readFile(path, callback) | Simple async code |
| Sync (blocking) | fs.readFileSync(path) | Startup scripts, one-time operations |
| Promise (modern async) | fs.promises.readFile(path) | Modern async/await code (RECOMMENDED) |
Always prefer the Promise version (fs.promises) for production code. It's non-blocking and works beautifully with async/await.
Reading a file is like reading your chai tapri menu. Let's say you have a file called menu.txt:
--- Chai Tapri Menu ---
Ginger Chai - Rs. 10
Elaichi Chai - Rs. 12
Special Chai - Rs. 15
Biscuit (Parle-G) - Rs. 5
Samosa - Rs. 15
1. Callback version (old style):
const fs = require('fs');
fs.readFile('menu.txt', 'utf8', (err, data) => {
if (err) {
console.error('Error reading menu:', err.message);
return;
}
console.log('Menu loaded!');
console.log(data);
});
console.log('Reading menu...'); // This runs FIRST (non-blocking!)
2. Synchronous version (blocking — use sparingly):
const fs = require('fs');
try {
const data = fs.readFileSync('menu.txt', 'utf8');
console.log('Menu loaded!');
console.log(data);
} catch (err) {
console.error('Error:', err.message);
}
// ⛔ This BLOCKS the event loop until file is read!
3. Promise version (RECOMMENDED — modern):
const fs = require('fs/promises'); // Note: fs/promises
async function loadMenu() {
try {
const data = await fs.readFile('menu.txt', 'utf8');
console.log('Menu loaded!');
console.log(data);
} catch (err) {
console.error('Error:', err.message);
}
}
loadMenu();
console.log('This runs first — non-blocking!');
Key options for readFile:
'utf8'— Returns file content as a string (without it, you get a Buffer)- No encoding — Returns a raw Buffer (binary data, images, files)
Buffer vs String: Without 'utf8', readFile returns a Buffer object. For text files, always pass 'utf8'. For images or binary files, use Buffer.
Writing files is like updating your chai menu when prices change or adding new orders.
1. Writing a new file (overwrites if exists):
const fs = require('fs/promises');
async function writeMenu() {
const newMenu = `--- Chai Tapri Menu (UPDATED) ---
Ginger Chai - Rs. 12 (price increased!)
Elaichi Chai - Rs. 15
Special Chai - Rs. 20
Biscuit (Parle-G) - Rs. 5
Samosa - Rs. 15
Cold Coffee (NEW!) - Rs. 25`;
await fs.writeFile('menu.txt', newMenu, 'utf8');
console.log('Menu updated successfully!');
}
writeMenu();
2. Appending to a file (add without overwriting):
await fs.appendFile('orders.log', `New order: Ginger Chai at ${new Date()}\n`, 'utf8');
console.log('Order logged!');
// appendFile adds to the END of the file, doesn't overwrite existing content
3. Using writeFile flags for more control:
// Flag: 'w' — Write (default, overwrites)
await fs.writeFile('menu.txt', data, { flag: 'w' });
// Flag: 'a' — Append (same as appendFile)
await fs.writeFile('orders.log', data, { flag: 'a' });
// Flag: 'wx' — Write, but FAIL if file exists (prevents overwriting!)
await fs.writeFile('backup.json', data, { flag: 'wx' });
// Throws error if backup.json already exists — safe for backups!
Real Hyderabad use case — Order logging:
const fs = require('fs/promises');
async function logOrder(customer, item, price) {
const timestamp = new Date().toISOString();
const logLine = `[${timestamp}] ${customer} ordered ${item} - Rs. ${price}\n`;
await fs.appendFile('orders.log', logLine, 'utf8');
console.log(`Order logged for ${customer}`);
}
// Usage:
// await logOrder('Raju', 'Special Chai', 20);
// await logOrder('Priya', 'Samosa', 15);
Every time someone orders, it's appended to orders.log. At end of day, the log file shows all orders — no database needed!
Directory operations help you manage your kitchen storage — organize files into folders, check what's available, create backups.
1. Reading a directory (see all files in a folder):
const fs = require('fs/promises');
async function listKitchen() {
const files = await fs.readdir('./kitchen');
console.log('Kitchen contents:', files);
// Output: [ 'chai-patti.txt', 'sugar.txt', 'menu.txt', 'orders.log' ]
}
listKitchen();
2. Creating a directory:
await fs.mkdir('./backups');
console.log('Backups folder created!');
// Create nested directories (like mkdir -p)
await fs.mkdir('./data/orders/2024', { recursive: true });
console.log('Nested folders created!');
3. Checking if a file or directory exists:
import { access, constants } from 'fs/promises';
async function checkExists(path) {
try {
await access(path, constants.F_OK);
console.log(`${path} exists!`);
return true;
} catch {
console.log(`${path} does not exist`);
return false;
}
}
await checkExists('menu.txt');
await checkExists('biryani.txt');
4. Renaming and deleting:
// Rename file
await fs.rename('old-menu.txt', 'new-menu.txt');
// Delete file
await fs.unlink('old-recipe.txt');
// Delete directory (must be empty)
await fs.rmdir('./empty-folder');
// Delete directory and everything inside (like rm -rf)
await fs.rm('./backups', { recursive: true, force: true });
These operations are essential for file management in any real application — creating upload folders, organizing logs, managing backups, and cleaning up temp files.
Sometimes you need to know more about a file than just its content — like its size, when it was created, when it was last modified. And sometimes you want to watch for changes — like a chef watching when new ingredients arrive.
1. File stats (size, dates, permissions):
const fs = require('fs/promises');
async function getFileInfo(path) {
const stats = await fs.stat(path);
console.log('File info for:', path);
console.log('Size:', stats.size, 'bytes');
console.log('Created:', stats.birthtime);
console.log('Modified:', stats.mtime);
console.log('Is file:', stats.isFile());
console.log('Is directory:', stats.isDirectory());
// File size in human-readable format
if (stats.size < 1024) {
console.log(`${stats.size} bytes`);
} else {
console.log(`${(stats.size / 1024).toFixed(1)} KB`);
}
}
getFileInfo('menu.txt');
2. Watching a file for changes (real-time):
const fs = require('fs');
// Watch a file — runs callback whenever the file changes
fs.watch('menu.txt', (eventType, filename) => {
console.log(`Event: ${eventType}`);
console.log(`File changed: ${filename}`);
console.log('Menu updated! Reloading...');
// You could re-read the file here
});
console.log('Watching menu.txt for changes...');
// Now go edit menu.txt in your editor — you'll see the watch trigger!
3. Watch multiple files in a directory:
// Watch an entire directory
fs.watch('./kitchen', { recursive: true }, (event, filename) => {
console.log(`${filename} changed (${event})`);
// Useful for auto-reloading servers during development!
});
console.log('Watching kitchen directory...');
File watching is how tools like nodemon work — they watch your files and restart the server when anything changes. It's also used for live reload in development, monitoring config files, and watching log directories.
Stage 1 Complete! ➕ You now know: what Node.js is, npm and package.json, how to create an HTTP server, how modules work, and how to read/write files. Next up: Stage 2 — Express Routes!
Key Takeaways
- ✅ fs module is built-in — no npm install needed. Has 3 APIs: callbacks, sync, promises.
- ✅ Always prefer fs.promises (Promise version) for production — non-blocking + async/await.
- ✅ readFile reads files, writeFile writes/overwrites, appendFile adds to end.
- ✅ Pass 'utf8' encoding for text files. Without it, you get a Buffer (binary data).
- ✅ Use { recursive: true } with mkdir for nested directory creation.
- ✅ fs.watch() lets you monitor files/directories for changes in real-time.
- ✅ fs.stat() gives detailed file info: size, creation date, modification date, type.
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login