Ralph
Ralph

Reputation: 2095

nodejs read file, write to temporary file then copy and replace the original file

I am trying to read the file, then create a temporary file then copy and replace the temporary file to the original file at the end.

Is it possible to do the following?

// read the original file then save it to temporary file
fs.readFile(originalPath, function (err, data) {
            var json = JSON.parse(data);
            json.items.push("sample item");
            fs.writeFileSync(tmpPath, JSON.stringify(json))
})

// copy the temporary file to the original file path
fs.readFile(tmpPath, (err, contents) => {
            var json = JSON.parse(contents);
            fs.writeFileSync(originalPath, JSON.stringify(json));
});

I am doing this to prevent the changes made to original file until the process has been completed.

It doesn't seem to work due the the file is not physically saved when reading it.

Thanks.

Upvotes: 3

Views: 5905

Answers (2)

Matt
Matt

Reputation: 74680

The copy/edit/replace might be easier to reason with async/await promises that flow like normal code than with callbacks.

fs provides a promise API:

const fsp = require('fs').promises

Then the code can flow from top to bottom by using await for any asynchronous tasks.

// read the original file then save it to temporary file
async function modifyFile(originalPath, tmpPath, item){
  const data = await fsp.readFile(originalPath)

  const json = JSON.parse(data)
  json.items.push(item)

  // Save it
  await fsp.writeFile(tmpPath, JSON.stringify(json))
  await fsp.renameFile(tmpPath, originalPath)
}

modifyFile('orig.json', 'orig.json.tmp', 'new item').catch(console.error)

Note that async/await are ES2017 and require Node.js 7.6+ or a compiler like Babel.

Upvotes: 3

kshetline
kshetline

Reputation: 13682

I'm not sure I followed all that you were trying to do from that short code snippet, but it's possible that you could get into some trouble mixing asynchronous file reading and synchronous file writing like that.

If those two line ran one after the other as you have them written, the second readFile wouldn't see the output created by the writeFileSync that's above it -- the tmpPath file wouldn't have been written to yet.

Upvotes: 3

Related Questions