Reliable way to strip BOM from a stream
Till recently I've used this way (this demo script reads and outputs itself line by line):
const fs = require('fs'); const rl = require('readline'); let lineNumber = 0; rl.createInterface({ input: fs.createReadStream(__filename, { encoding: 'utf8' }), }).on('line', line => { if (++lineNumber === 1) line = line.replace(/^\uFEFF/, ''); console.log(line); }).on('close', () => { console.log('EOF'); });
However, it makes me uneasy that each iteration except the first one should increment and compare the lineNumber in vain. So I've come to this solution:
const fs = require('fs'); const rl = require('readline'); const input = fs.createReadStream(__filename, { encoding: 'utf8' }); input.once('readable', () => { const maybeBOM = input.read(1); if (maybeBOM !== '\uFEFF') input.unshift(maybeBOM); rl.createInterface({ input, }).on('line', line => { console.log(line); }).on('close', () => { console.log('EOF'); }); });
However, now I doubt if this flow is reliable. Could it somehow mess up the stream internal mechanics? Is this sequence of stream modes and methods safe?