如何检查文件是否存在?


当前回答

编辑: 从节点v10.0.0开始,我们可以使用fs.promises.access(…)

检查文件是否存在的异步代码示例:

function checkFileExists(file) {
  return fs.promises.access(file, fs.constants.F_OK)
           .then(() => true)
           .catch(() => false)
}

stat的替代方法可能是使用新的fs.access(…):

简化的短承诺函数检查:

s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))

示例用法:

let checkFileExists = s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
checkFileExists("Some File Location")
  .then(bool => console.log(´file exists: ${bool}´))

扩大承诺方式:

// returns a promise which resolves true if file exists:
function checkFileExists(filepath){
  return new Promise((resolve, reject) => {
    fs.access(filepath, fs.constants.F_OK, error => {
      resolve(!error);
    });
  });
}

或者如果你想同步操作:

function checkFileExistsSync(filepath){
  let flag = true;
  try{
    fs.accessSync(filepath, fs.constants.F_OK);
  }catch(e){
    flag = false;
  }
  return flag;
}

其他回答

异步版本!还有承诺版本!这里有干净简单的方法!

try {
    await fsPromise.stat(filePath);
    /**
     * File exists!
     */
    // do something
} catch (err) {
    if (err.code = 'ENOENT') {
        /**
        * File not found
        */
    } else {
        // Another error!
    }
}

我的代码中的一个更实用的片段来更好地说明:


try {
    const filePath = path.join(FILES_DIR, fileName);
    await fsPromise.stat(filePath);
    /**
     * File exists!
     */
    const readStream = fs.createReadStream(
        filePath,
        {
            autoClose: true,
            start: 0
        }
    );

    return {
        success: true,
        readStream
    };
} catch (err) {
    /**
     * Mapped file doesn't exists
     */
    if (err.code = 'ENOENT') {
        return {
            err: {
                msg: 'Mapped file doesn\'t exists',
                code: EErrorCode.MappedFileNotFound
            }
        };
    } else {
        return {
            err: {
                msg: 'Mapped file failed to load! File system error',
                code: EErrorCode.MappedFileFileSystemError
            }
        }; 
   }
}

上面的例子只是为了演示!我可以使用读流的错误事件!捕捉任何错误!跳过这两个电话!

在node14中使用typescript和fs/promises

import * as fsp from 'fs/promises';
try{
const = await fsp.readFile(fullFileName)
...
} catch(e) { ...}

最好使用fsp。readFile than fsp。定子fsp。访问有两个原因:

最不重要的原因是少了一个机会。 有可能fsp。statand fsp。readFile会给出不同的答案。要么是因为他们所问问题的细微差异,要么是因为文件状态在两次调用之间发生了变化。因此编码器必须为两个而不是一个条件分支编码,用户可能会看到更多的行为。

我是这样做的,详见https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback

fs.access('./settings', fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK, function(err){
  console.log(err ? 'no access or dir doesnt exist' : 'R/W ok');

  if(err && err.code === 'ENOENT'){
    fs.mkdir('settings');
  }
});

这有什么问题吗?

异步等待风格的简洁解决方案:

import { stat } from 'fs/promises';

const exists = await stat('foo.txt')
   .then(() => true)
   .catch(() => false);

一种更简单的同步方法。

if (fs.existsSync('/etc/file')) {
    console.log('Found file');
}

API文档说明了existsSync是如何工作的: 通过检查文件系统来测试给定路径是否存在。