const fs = require('fs');
const path = require('path');
// Function to create and handle a ReadStream with proper error handling
function readWithErrorHandling(filePath) {
console.log(`Attempting to read: ${filePath}`);
// Create the ReadStream
const readStream = fs.createReadStream(filePath);
// Set up promise to capture result or error
return new Promise((resolve, reject) => {
let data = '';
// Handle data events
readStream.on('data', (chunk) => {
data += chunk;
});
// Handle successful completion
readStream.on('end', () => {
console.log(`Successfully read ${readStream.bytesRead} bytes from ${filePath}`);
resolve(data);
});
// Handle errors
readStream.on('error', (err) => {
console.error(`Error reading ${filePath}: ${err.message}`);
reject(err);
});
// Handle stream closure (always happens, even if there's an error)
readStream.on('close', () => {
console.log(`Stream for ${filePath} closed`);
});
});
}
// Test with both existing and non-existing files
const existingFile = path.join(__dirname, 'test-existing.txt');
const nonExistingFile = path.join(__dirname, 'non-existing-file.txt');
// Create the test file
fs.writeFileSync(existingFile, 'This is test content for error handling example');
// Example 1: Reading an existing file
console.log('Example 1: Reading an existing file');
readWithErrorHandling(existingFile)
.then(data => {
console.log('File content:', data);
// Example 2: Reading a non-existing file
console.log('\nExample 2: Reading a non-existing file');
return readWithErrorHandling(nonExistingFile);
})
.catch(err => {
console.log('Error caught in Promise catch:', err.message);
})
.finally(() => {
// Clean up the test file
if (fs.existsSync(existingFile)) {
fs.unlinkSync(existingFile);
console.log('Test file removed');
}
});
// Example 3: Demonstrating destroyed streams
console.log('\nExample 3: Demonstrating destroyed streams');
const destroyTestFile = path.join(__dirname, 'destroy-test.txt');
fs.writeFileSync(destroyTestFile, 'A'.repeat(10000));
const destroyStream = fs.createReadStream(destroyTestFile);
destroyStream.on('data', (chunk) => {
console.log(`Received ${chunk.length} bytes before destroying the stream`);
// Destroy the stream after receiving the first chunk
console.log('Deliberately destroying the stream');
destroyStream.destroy(new Error('Stream manually destroyed'));
});
destroyStream.on('error', (err) => {
console.error(`Destruction error: ${err.message}`);
});
destroyStream.on('close', () => {
console.log('Destroyed stream closed');
// Clean up
fs.unlinkSync(destroyTestFile);
console.log('Destroy test file removed');
});