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)
})
}
Related videos on Youtube

Comments
-
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 over 8 yearsWhat OS are you targeting? On Linux/OSX you can have Node.js watch a directory for changes.
-
Renato Gama over 8 yearsthis might be useful; nodejs.org/docs/latest/api/…
-
-
Sam Joseph over 5 yearsI don't find this so useful as fs.watch seems to need the file to exist before it can be watched ...
-
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 yearsWhy busy waiting?
-
MushyPeas about 1 yearWouldn't recommend using setInterval, it's an endless loop if the file never exists... very bad.
-
MushyPeas about 1 yearsetTimeout should reject, or resolve with false boolean, now it's always passing, no matter if file exists or not