fs.exists,fs.existsSync - 为什么要弃用?

Cal*_*dge 23 node.js

我注意到官方节点文档说了些令人吃惊的事情fs.exists:

"fs.exists()是一种时代错误,只是出于历史原因而存在.几乎从来没有理由在你自己的代码中使用它.

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

我理解这个建议,打开一个文件,然后处理错误,如果它不存在,但我不明白的是为什么界面被弃用而不是简单地改变实现.

任何人都可以向我解释为什么检查文件的存在与API一样简单和逻辑,这fs.exists是一件坏事,它应该被称为反模式并从节点API中删除?

DDN*_*hep 9

不需要使用fs.stat(),因为fs.existsSync()尚未弃用.

https://nodejs.org/api/fs.html#fs_fs_existssync_path

fs.existsSync(路径)

添加于:v0.1.21路径| fs.exists()的同步版本.如果文件存在则返回true,否则返回false.

请注意,不推荐使用fs.exists(),但不推荐使用fs.existsSync().(fs.exists()的callback>参数接受与其他> Node.js回调不一致的参数.fs.existsSync()不使用回调.)

  • 虽然这个答案是正确的,但最好使用非阻塞解决方案。Node.js 的这篇文章解释了阻塞和非阻塞文件系统调用之间的区别。https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/ (2认同)

SLa*_*aks 7

因为你引用的第二段。

检查文件是否存在是没有意义的,因为它总是可能在检查后立即被删除。


ris*_*sto 7

我认为这是因为它是多余的.您可以尝试打开文件来检查文件是否存在.ENOENT如果它不存在它会给你:

> fs.open('foo', 'r', function(err, fd) {
    ... console.log(err, fd);
    ... 
})
undefined
> { [Error: ENOENT, open 'foo'] errno: 34, code: 'ENOENT', path: 'foo' } undefined
Run Code Online (Sandbox Code Playgroud)

  • 您可能想要检查文件是否存在而无需打开它!例如,如果要阻止用户创建名称已存在的文件,如果要确保文件是否未在外部删除等. (15认同)
  • `if (fs.existsSync('somefile'))` 和 `var exists = false; 之间有很大的不同;尝试 { fs.statSync('somefile'); 存在 = 真;} catch (e) { } if (exists)`。也就是说,后者超级烦人。fs.existsSync 是一个很好的包装器。 (3认同)
  • 我还可以补充一点,调用exists() 而不是open() 更“有表现力”,在这种情况下,exists() 使我的意图更加明确。 (2认同)

Mic*_*ael 5

不赞成使用,因为有人说这是一种反模式。也就是说,信任existant()然后对文件进行操作并不安全,因为可以在exists-call和doing-something-call之间删除文件。

我同意以上情况。但是对我来说,存在更多现存的()用途。我将空的虚拟文件放在临时目录和缓存目录中。当我执行危险的操作时,例如从缓存目录中删除旧文件,我会寻找我的虚拟文件以确保我不在错误的目录中操作。即,我只需要确认文件在那里。存在对此非常适合该法案,但是我想我将改用stat()。