Q1. How do you work with file streams in Node.js?
Streams are used for reading/writing large files efficiently without loading them entirely into memory. fs.createReadStream() and fs.createWriteStream() create readable/writable streams. Example:
const readStream = fs.createReadStream('largefile.txt'); readStream.on('data', (chunk) => { ... }); Streams are event-based and memory-efficient.Q2. What are file descriptors and how do you use them?
A file descriptor is a number that uniquely identifies an open file. fs.open() opens a file and returns a descriptor. Then you can use fs.read() and fs.write() with the descriptor for more control. Example:
fs.open('file.txt', 'r', (err, fd) => { ... }); Always close descriptors with fs.close() when done.Q3. How do you check if a file exists?
Modern Node.js recommends using fs.access() to check file existence. Example:
fs.access('file.txt', fs.constants.F_OK, (err) => { console.log(err ? 'does not exist' : 'exists') });. The old fs.exists() is deprecated. You can also use fs.stat() and check if it's a file.Q4. How do you change file permissions?
Use fs.chmod() to change file permissions. Example:
fs.chmod('file.txt', 0o755, (err) => { ... }); The mode is specified as an octal number. 0o755 means owner can read/write/execute, group and others can read/execute. fs.constants provides constants like fs.constants.S_IRUSR for read permission.Q5. How do you handle file errors properly?
Always check the error object in callbacks. Common error codes: ENOENT (file not found), EACCES (permission denied), EISDIR (is a directory), ENOTDIR (not a directory). Use switch or if statements on err.code to handle specific errors. For async/await, wrap in try/catch blocks.
