Nodejs check file exists, if not, wait till it exist

24,905

Solution 1

Assuming you're planning on using Promises since you did not supply a callback in your method signature, you could check if the file exists and watch the directory at the same time, then resolve if the file exists, or the file is created before the timeout occurs.

function checkExistsWithTimeout(filePath, timeout) {
    return new Promise(function (resolve, reject) {
        var timer = setTimeout(function () {
            watcher.close();
            reject(new Error('File did not exists and was not created during the timeout.'));
        }, timeout);
        fs.access(filePath, fs.constants.R_OK, function (err) {
            if (!err) {
                clearTimeout(timer);
                watcher.close();
                resolve();
            }
        });
        var dir = path.dirname(filePath);
        var basename = path.basename(filePath);
        var watcher = fs.watch(dir, function (eventType, filename) {
            if (eventType === 'rename' && filename === basename) {
                clearTimeout(timer);
                watcher.close();
                resolve();
            }
        });
    });
}

Solution 2

fs.watch() API is what you need.

Be sure to read all the caveats mentioned there before you use it.

Solution 3

Here is the solution:

// Wait for file to exist, checks every 2 seconds by default
function getFile(path, timeout=2000) {
    const intervalObj = setInterval(function() {
        const file = path;
        const fileExists = fs.existsSync(file);
        console.log('Checking for: ', file);
        console.log('Exists: ', fileExists);
        if (fileExists) {
            clearInterval(intervalObj);
        }
    }, timeout);
};

Solution 4

function holdBeforeFileExists(filePath, timeout) {
   timeout = timeout < 1000 ? 1000 : timeout;
   return new Promise((resolve)=>{  
       var timer = setTimeout(function () {
           resolve();
       },timeout);
       var inter = setInterval(function () {
       if(fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()){
           clearInterval(inter);
           clearTimeout(timer);
           resolve();
       }
     }, 100);
  });
}

Solution 5

You could implement it like this if you have node 6 or higher.

const fs = require('fs')
function checkExistsWithTimeout(path, timeout) {
  return new Promise((resolve, reject) => {
    const timeoutTimerId = setTimeout(handleTimeout, timeout)
    const interval = timeout / 6
    let intervalTimerId
    function handleTimeout() {
      clearTimeout(timerId)
      const error = new Error('path check timed out')
      error.name = 'PATH_CHECK_TIMED_OUT'
      reject(error)
    }
    function handleInterval() {
      fs.access(path, (err) => {
        if(err) {
          intervalTimerId = setTimeout(handleInterval, interval)
        } else {
          clearTimeout(timeoutTimerId)
          resolve(path)
        }
      })
    }
    intervalTimerId = setTimeout(handleInterval, interval)
  })
}
Share:
24,905

Related videos on Youtube

wong2
Author by

wong2

Actively maintaining https://github.com/wong2/pick

Updated on November 20, 2021

Comments

  • wong2
    wong2 over 1 year

    I'm generating files automatically, and I have another script which will check if a given file is already generated, so how could I implement such a function:

    function checkExistsWithTimeout(path, timeout)
    

    which will check if a path exists, if not, wait for it, util timeout.

    • Brad
      Brad over 8 years
      What OS are you targeting? On Linux/OSX you can have Node.js watch a directory for changes.
    • Renato Gama
      Renato Gama over 8 years
      this might be useful; nodejs.org/docs/latest/api/…
  • Sam Joseph
    Sam Joseph over 5 years
    I don't find this so useful as fs.watch seems to need the file to exist before it can be watched ...
  • Anthony O.
    Anthony O. over 4 years
    @SamJoseph you can watch the parent directory and wait for an event that will say that the file you are waiting for has just arrived.
  • Константин Ван
    Константин Ван over 4 years
    Why busy waiting?
  • MushyPeas
    MushyPeas about 1 year
    Wouldn't recommend using setInterval, it's an endless loop if the file never exists... very bad.
  • MushyPeas
    MushyPeas about 1 year
    setTimeout should reject, or resolve with false boolean, now it's always passing, no matter if file exists or not

Related