Home > database >  why does ending a write stream clears data that was previously written to that file in nodeJS
why does ending a write stream clears data that was previously written to that file in nodeJS

Time:12-08

i was trying to read content of one file and write it to another using nodeJS.everything works if i do not add fileStream.end(). Below is the code i have written:

    const fs= require ('fs');
    const readLine = require('readline');

    //read file
    const myInterface = readLine.createInterface({input:fs.createReadStream('./input/file.txt'),output: fs.createWriteStream('output.txt')});

//print to output
const fileStream=fs.createWriteStream('output1.txt');

//function to copy 
let copyData=(line)=>{
    //console.log(line);
    fileStream.write(`copied: ${line}\n`);
}

//copy file
myInterface.on('line',copyData);
fileStream.end();

//print to console
fs.readFile('output1.txt','utf-8',(err,data)=>{
    if(err)
    console.log(`ERROR: ${err}`)
    else
    console.log(`readFile: ${data}`)
})

Thanks in advance! added the picture of the terminal output enter image description here

CodePudding user response:

You're calling filestream.end() synchronously before any of the reading and writing has completed.

When you do this:

myInterface.on('line',copyData);

you're just setting up an event handler and sometime IN THE FUTURE, the function copyData will be called with each line from the file. But, before any of that even happens, you call:

filestream.end()

which shuts down the writestream before anything has been written to it.


Similarly, you're also calling fs.readFile() before the reading/writing has completed.

This is all an event driven system. When you set up asynchronous operations like you have here and you want to do something upon completion of the operation, then you can't just call that code synchronously like you are here because the asynchronous events won't have finished yet. Instead, you need to register for completion events and trigger your "after" work on the completion events.

In this case, you can listen for the close event on the input stream.

const fs = require('fs');
const readLine = require('readline');

//read file
const myInterface = readLine.createInterface({ input: fs.createReadStream('./input/file.txt')});

//print to output
const fileStream = fs.createWriteStream('output1.txt');

//function to copy 
let copyData = (line) => {
  //console.log(line);
  fileStream.write(`copied: ${line}\n`);
}

//copy file
myInterface.on('line', copyData);

// see when the read stream is done
myInterface.on('close', () => {
  fileStream.end();
  //print to console
  fs.readFile('output1.txt', 'utf-8', (err, data) => {
    if (err)
      console.log(`ERROR: ${err}`)
    else
      console.log(`readFile: ${data}`)
  })
});
// listen for errors too
myInterface.on('error', err => {
  console.log(err);
});
  • Related