【问题标题】:Nodejs check file exists, if not, wait till it existnodejs检查文件是否存在,如果不存在,等到存在
【发布时间】:2014-11-27 17:33:25
【问题描述】:

我正在自动生成文件,并且我有另一个脚本将检查给定文件是否已经生成,那么我该如何实现这样的功能:

function checkExistsWithTimeout(path, timeout)

它将检查路径是否存在,如果不存在,则等待它,util timeout。

【问题讨论】:

标签: node.js


【解决方案1】:

fs.watch() API 就是你所需要的。

在使用它之前,请务必阅读其中提到的所有注意事项。

【讨论】:

  • 我不觉得这很有用,因为 fs.watch 似乎需要文件存在才能被观看......
  • @SamJoseph 你可以观察父目录并等待一个事件,表明你等待的文件刚刚到达。
【解决方案2】:

这在很大程度上是一种 hack,但适用于快速的东西。

function wait (ms) {
    var now = Date.now();
    var later = now + ms;
    while (Date.now() < later) {
        // wait
    }
}

【讨论】:

  • 为什么忙着等待?
【解决方案3】:

解决办法如下:

// 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);
};

【讨论】:

    【解决方案4】:

    如果你有节点 6 或更高版本,你可以这样实现它。

    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)
      })
    }
    

    【讨论】:

      【解决方案5】:

      假设您计划使用Promises,因为您没有在方法签名中提供回调,您可以检查文件是否存在并同时查看目录,然后解析文件是否存在,或者文件在超时发生之前创建。

      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();
                  }
              });
          });
      }
      

      【讨论】:

      • 如果不能确保目录确实存在怎么办?如何观看./NONEXISTENT1/NONEXISTENT2/NONEXISTENT3/test
      • 我试过了,但它在第一个 watcher.close() 上引发了错误;
      【解决方案6】:
      function verifyFileDownload(extension) {
          browser.sleep(150000); //waiting for file to download
          const fs = require('fs');
          let os = require('os');
          var flag = true;
          console.log(os.userInfo());
          fs.readdir('/Users/' + require("os").userInfo().username + '/Downloads/', (error, file) => {
              if (error) {
                  throw error;
              }
              console.log('File name' + file);
              for (var i = 0; i < file.length; i++) {
                  const fileParts = file[i].split('.');
                  const ext = fileParts[fileParts.length - 1];
                  if (ext === extension) {
                      flag = false;
                  }
              }
              if (!flag) {
                  return;
              }
              throw error;
          });
      };
      

      【讨论】:

        【解决方案7】:
        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);
          });
        }
        

        【讨论】:

          【解决方案8】:

          这里有另一个适合我的版本:

          async function checkFileExist(path, timeout = 2000)
          {
              let totalTime = 0; 
              let checkTime = timeout / 10;
          
              return await new Promise((resolve, reject) => {
                  const timer = setInterval(function() {
          
                      totalTime += checkTime;
              
                      let fileExists = fs.existsSync(path);
              
                      if (fileExists || totalTime >= timeout) {
                          clearInterval(timer);
                          
                          resolve(fileExists);
                          
                      }
                  }, checkTime);
              });
          
          }
          

          你可以简单地使用它:

          await checkFileExist("c:/tmp/myfile.png");
          

          【讨论】:

            猜你喜欢
            • 2019-08-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-11-22
            • 1970-01-01
            • 1970-01-01
            • 2022-11-06
            • 2021-02-19
            相关资源
            最近更新 更多