lib/fsExt.js
function getFileInfo(fileId, filePath, cb, repeated){ // cb(err, fileInfo)
    repeated = repeated || 0;
    var fullPath = resolve(filePath).fullPath;
    
    fs.exists(fullPath, function(exists){
        if(!exists) cb();
        else fs.stat(fullPath, function(err, stat){
            if(err && err.code === 'ENOENT') { // directory or file removed, just skip it
                cb();
            }
            else if(err && repeated < 5) setTimeout(function(){
                getFileInfo(fileId, fullPath, cb, repeated+1);
            }, 200);
            else if(err) cb(err);
            else cb(null, getFileItem(fileId, stat, fullPath));
        });
    });
}
function getFileInfo(fileId, filePath, cb, repeated){ // cb(err, fileInfo)
    repeated = repeated || 0;
    var fullPath = resolve(filePath).fullPath;
    
    fs.exists(fullPath, function(exists){
        if(!exists) cb();
        else fs.stat(fullPath, function(err, stat){
            if(err && err.code === 'ENOENT') { // directory or file removed, just skip it
                cb();
            }
            else if(err && repeated < 5) setTimeout(function(){
                getFileInfo(fileId, fullPath, cb, repeated+1);
            }, 200);
            else if(err) cb(err);
            else cb(null, getFileItem(fileId, stat, fullPath));
        });
    });
}
get resolved file info & stats
@param {String} fileId
@param {String} fullPath
@param {Function} cb
@param {Integer} repeated