同步检查Node.js中是否存在文件/目录

如何使用node.js同步检查文件或目录是否存在?


这个问题的答案多年来一直在改变。 目前的答案在这里排在首位,随后是按时间顺序排列的各种答案:

当前答案

你可以使用fs.existsSync()

var fs = require('fs');
if (fs.existsSync(path)) {
    // Do something
}

它已被弃用好几年了,但不再是了。 从文档:

请注意, fs.exists()已弃用,但fs.existsSync()不适用。 ( fs.exists()的回调参数接受与其他Node.js回调不一致的参数fs.existsSync()不使用回调。)

您特别要求进行同步检查,但如果您可以使用异步检查(通常最好使用I / O),请使用fs.access (因为exists已被弃用)。


历史答案

以下是按时间顺序排列的历史答案:

  • 2010年的原始答案
    stat / statSynclstat / lstatSync
  • 2012年9月更新
    exists / existsSync
  • 2015年2月更新
    (注意即将到来的exists / existsSync弃用,所以我们可能会回到stat / statSynclstat / lstatSync
  • 2015年12月更新
    (还有fs.access(path, fs.F_OK, function(){}) / fs.accessSync(path, fs.F_OK) ,但是请注意,如果文件/目录不存在,这是一个错误; docs for fs.stat建议使用fs.access如果您需要检查存在而不打开)
  • 2016年12月更新
    fs.exists()仍然被弃用,但fs.existsSync()不再被弃用。 所以你现在可以安全地使用它。
  • 2010年的原始答案:

    你可以使用statSynclstatSync (docs link),它给你一个fs.Stats对象。 通常,如果某个功能的同步版本可用,则它将与具有Sync的异步版本具有相同的名称。 所以statSyncstat的同步版本; lstatSynclstat的同步版本等

    lstatSync告诉你是否存在,如果是,是文件还是目录(或者在某些文件系统中,符号链接,块设备,字符设备等),例如,如果你需要知道它是否存在,是一个目录:

    var fs = require('fs');
    try {
        // Query the entry
        stats = fs.lstatSync('/the/path');
    
        // Is it a directory?
        if (stats.isDirectory()) {
            // Yes it is
        }
    }
    catch (e) {
        // ...
    }
    

    ...类似的,如果它是一个文件,那就是isFile ; 如果它是一个块设备,则有isBlockDevice等等。注意try/catch ; 如果条目根本不存在,它会引发错误。

    如果您不关心条目是什么并且只想知道它是否存在,则可以使用path.existsSync指出的path.existsSync(或with latest, fs.existsSync ):

    var path = require('path');
    if (path.existsSync("/the/path")) { // or fs.existsSync
        // ...
    }
    

    它不需要try/catch ,但不会告诉你什么是事情,只是它在那里。 很久以前, path.existsSync已被弃用。


    附注:你明确地问过如何同步检查,所以我使用了上述函数的xyzSync版本。 但只要有可能,对于I / O,最好避免同步调用。 从CPU的角度来看,调用I / O子系统需要花费大量的时间。 注意调用lstat而不是lstatSync是多么容易:

    // Is it a directory?
    lstat('/the/path', function(err, stats) {
        if (!err && stats.isDirectory()) {
            // Yes it is
        }
    });
    

    但是如果你需要同步版本,它就在那里。

    2012年9月更新

    几年前的下面的答案现在有点过时了。 目前的方法是使用fs.existsSync为文件/目录存在(或者当然fs.exists用于异步检查)执行同步检查,而不是下面的path版本。

    例:

    var fs = require('fs');
    
    if (fs.existsSync(path)) {
        // Do something
    }
    
    // Or
    
    fs.exists(path, function(exists) {
        if (exists) {
            // Do something
        }
    });
    

    2015年2月更新

    现在我们在2015年,Node文档现在说fs.existsSync (和fs.exists )“将被弃用”。 (因为节点人认为在打开它之前检查是否存在某些东西是愚蠢的,这是否是检查是否存在某个东西的唯一原因!)

    所以我们可能会回到各种stat方法......直到/除非再次改变,当然。

    2015年12月更新

    不知道它有多久,但也有fs.access(path, fs.F_OK, ...) / fs.accessSync(path, fs.F_OK) 。 至少从2016年10月开始, fs.stat文档建议使用fs.access进行存在检查(“为了检查文件是否存在而未经处理,建议使用fs.access() ”)。 但请注意,访问不可用被认为是错误,所以如果您期望文件可访问,这可能是最好的:

    var fs = require('fs');
    
    try {
        fs.accessSync(path, fs.F_OK);
        // Do something
    } catch (e) {
        // It isn't accessible
    }
    
    // Or
    
    fs.access(path, fs.F_OK, function(err) {
        if (!err) {
            // Do something
        } else {
            // It isn't accessible
        }
    });
    

    2016年12月更新

    你可以使用fs.existsSync()

    if (fs.existsSync(path)) {
        // Do something
    }
    

    它已被弃用好几年了,但不再是了。 从文档:

    请注意, fs.exists()已弃用,但fs.existsSync()不适用。 ( fs.exists()的回调参数接受与其他Node.js回调不一致的参数fs.existsSync()不使用回调。)


    查看源代码,有一个同步版本的path.exists - path.existsSync 。 看起来它在文档中错过了。

    更新:

    现在不推荐使用 path.existspath.existsSync 。 请使用fs.existsfs.existsSync

    2016年更新:

    fs.exists和fs.existsSync也被弃用 。 改为使用fs.stat()或fs.access()。


    使用目前推荐的(截至2015年)API(每个Node文档),这就是我所做的:

    var fs = require('fs');
    
    function fileExists(filePath)
    {
        try
        {
            return fs.statSync(filePath).isFile();
        }
        catch (err)
        {
            return false;
        }
    }
    

    针对@broadband在评论中提出的EPERM问题,提出了一个很好的观点。 在很多情况下,fileExists()可能不是一个很好的思考方式,因为fileExists()不能真正承诺布尔返回。 您可能能够确定文件存在或不存在,但是您也可能会收到权限错误。 权限错误并不一定意味着该文件存在,因为您可能缺少包含您正在检查的文件的目录的权限。 当然,有可能在检查文件存在时遇到其他一些错误。

    所以我上面的代码真的是doesFileExistAndDoIHaveAccessToIt(),但你的问题可能是doesFileNotExistAndCouldICreateIt(),这将是完全不同的逻辑(这将需要考虑EPERM错误,等等)。

    虽然fs.existsSync的回答直接解决了这里提出的问题,但这通常不会成为你想要的(你不只是想知道某条路上是否存在“某些东西”,你可能会关心“事物”存在的是文件或目录)。

    底线是,如果你检查是否存在一个文件,你可能是这样做的,因为你打算根据结果采取一些行动,并且该逻辑(检查和/或后续行动)应该适应这个想法在该路径中发现的东西可能是文件或目录,并且在检查过程中可能会遇到EPERM或其他错误。

    链接地址: http://www.djcxy.com/p/52269.html

    上一篇: Check synchronously if file/directory exists in Node.js

    下一篇: Spell checking message strings in .Net projects