如何在不使用fs.exists的情况下检查文件或目录是否存在?

时间:2023-02-08 07:11:54

The reason I ask, is because Node.js on ubuntu doesn't seem to have the fs.exists() function. Although I can call this when I run Node.js on my Mac, when I deploy to the server, it fails with an error saying the function does not exist.

我问的原因是因为ubuntu上的Node.js似乎没有fs.exists()函数。虽然我可以在我的Mac上运行Node.js时调用它,但是当我部署到服务器时,它会失败,并显示该函数不存在的错误。

Now, I am aware that some people consider it an "anti-pattern" to check if a file exists and then try and edit / open it etc, but in my case, I never delete these files, but I still need to check if they exist before writing to them.

现在,我知道有些人认为它是一个“反模式”来检查文件是否存在,然后尝试编辑/打开它等,但在我的情况下,我从不删除这些文件,但我仍然需要检查是否它们在写给他们之前就存在了。

So how can I check if the directory (or file) exists ?

那么如何检查目录(或文件)是否存在?

EDIT:

This is the code I run in a file called 'temp.'s' :

这是我在名为'temp。'的文件中运行的代码:

var fs=require('fs');
fs.exists('./temp.js',function(exists){
    if(exists){
        console.log('yes');
    }else{
        console.log("no");
    }
});

On my Mac, it works fine. On ubuntu I get the error:

在我的Mac上,它工作正常。在ubuntu上我收到错误:

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^ TypeError: Object #<Object> has no method 'exists'
    at Object.<anonymous> (/home/banana/temp.js:2:4)
    at Module._compile (module.js:441:26)
    at Object..js (module.js:459:10)
    at Module.load (module.js:348:32)
    at Function._load (module.js:308:12)
    at Array.0 (module.js:479:10)
    at EventEmitter._tickCallback (node.js:192:41)

On my Mac - version : v0.13.0-pre On Ubuntu - version : v0.6.12

在我的Mac上 - 版本:v0.13.0-pre在Ubuntu上 - 版本:v0.6.12

3 个解决方案

#1


7  

It's probably due to the fact that in NodeJs 0.6 the exists() method was located in the path module: http://web.archive.org/web/20111230180637/http://nodejs.org/api/path.htmltry-catch-finally

这可能是因为在NodeJs 0.6中,exists()方法位于路径模块中:http://web.archive.org/web/20111230180637/http://nodejs.org/api/path.html - 的try-catch-终于

^^ That comment answers why it isn't there. I'll answer what you can do about it (besides not using ancient versions).

^^那个评论回答为什么它不在那里。我会回答你能做些什么(除了不使用古代版本)。

From the fs.exists() documentation:

从fs.exists()文档:

In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to fs.exists() and fs.open(). Just open the file and handle the error when it's not there.

特别是,在打开文件之前检查文件是否存在是一种反模式,使您容易受到竞争条件的影响:另一个进程可能会在调用fs.exists()和fs.open()之间删除该文件。只需打开文件并在错误处理时处理错误。

You could do something like this:

你可以这样做:

fs.open('mypath','r',function(err,fd){
    if (err && err.code=='ENOENT') { /* file doesn't exist */ }
});

#2


6  

The accepted answer does not take into account that the node fs module documentation recommends using fs.stat to replace fs.exists (see the documentation).

接受的答案没有考虑到节点fs模块文档建议使用fs.stat替换fs.exists(请参阅文档)。

I ended up going with this:

我结束了这个:

function filePathExists(filePath) {
  return new Promise((resolve, reject) => {
    fs.stat(filePath, (err, stats) => {
      if (err && err.code === 'ENOENT') {
        return resolve(false);
      } else if (err) {
        return reject(err);
      }
      if (stats.isFile() || stats.isDirectory()) {
        return resolve(true);
      }
    });
  });
}

Note ES6 syntax + Promises - the sync version of this would be a bit simpler. Also my code also checks to see if there is a directory present in the path string and returns true if stat is happy with it - this may not be what everyone wants.

注意ES6语法+ Promises - 这个的同步版本会更简单一些。此外,我的代码还检查路径字符串中是否存在目录,如果stat对它感到满意则返回true - 这可能不是每个人都想要的。

#3


0  

The Sync methods don't have any way of notifying about an error. Except for exceptions! As it turns out, the fs.statSync method throws an exception when the file or directory doesn't exist. Creating the sync version is as easy as that:

Sync方法没有任何通知错误的方法。除了例外!事实证明,当文件或目录不存在时,fs.statSync方法会抛出异常。创建同步版本就像这样简单:

  function checkDirectorySync(directory) {
  try {
    fs.statSync(directory);
  } catch(e) {    
    try {
        fs.mkdirSync(directory);
    } catch(e) {
        return e;
    }
  }
}

And that's it. Using is as simple as before:

就是这样。使用就像以前一样简单:

checkDirectorySync("./logs");  
//directory created / exists, all good.

[]´z

#1


7  

It's probably due to the fact that in NodeJs 0.6 the exists() method was located in the path module: http://web.archive.org/web/20111230180637/http://nodejs.org/api/path.htmltry-catch-finally

这可能是因为在NodeJs 0.6中,exists()方法位于路径模块中:http://web.archive.org/web/20111230180637/http://nodejs.org/api/path.html - 的try-catch-终于

^^ That comment answers why it isn't there. I'll answer what you can do about it (besides not using ancient versions).

^^那个评论回答为什么它不在那里。我会回答你能做些什么(除了不使用古代版本)。

From the fs.exists() documentation:

从fs.exists()文档:

In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to fs.exists() and fs.open(). Just open the file and handle the error when it's not there.

特别是,在打开文件之前检查文件是否存在是一种反模式,使您容易受到竞争条件的影响:另一个进程可能会在调用fs.exists()和fs.open()之间删除该文件。只需打开文件并在错误处理时处理错误。

You could do something like this:

你可以这样做:

fs.open('mypath','r',function(err,fd){
    if (err && err.code=='ENOENT') { /* file doesn't exist */ }
});

#2


6  

The accepted answer does not take into account that the node fs module documentation recommends using fs.stat to replace fs.exists (see the documentation).

接受的答案没有考虑到节点fs模块文档建议使用fs.stat替换fs.exists(请参阅文档)。

I ended up going with this:

我结束了这个:

function filePathExists(filePath) {
  return new Promise((resolve, reject) => {
    fs.stat(filePath, (err, stats) => {
      if (err && err.code === 'ENOENT') {
        return resolve(false);
      } else if (err) {
        return reject(err);
      }
      if (stats.isFile() || stats.isDirectory()) {
        return resolve(true);
      }
    });
  });
}

Note ES6 syntax + Promises - the sync version of this would be a bit simpler. Also my code also checks to see if there is a directory present in the path string and returns true if stat is happy with it - this may not be what everyone wants.

注意ES6语法+ Promises - 这个的同步版本会更简单一些。此外,我的代码还检查路径字符串中是否存在目录,如果stat对它感到满意则返回true - 这可能不是每个人都想要的。

#3


0  

The Sync methods don't have any way of notifying about an error. Except for exceptions! As it turns out, the fs.statSync method throws an exception when the file or directory doesn't exist. Creating the sync version is as easy as that:

Sync方法没有任何通知错误的方法。除了例外!事实证明,当文件或目录不存在时,fs.statSync方法会抛出异常。创建同步版本就像这样简单:

  function checkDirectorySync(directory) {
  try {
    fs.statSync(directory);
  } catch(e) {    
    try {
        fs.mkdirSync(directory);
    } catch(e) {
        return e;
    }
  }
}

And that's it. Using is as simple as before:

就是这样。使用就像以前一样简单:

checkDirectorySync("./logs");  
//directory created / exists, all good.

[]´z