Node.js检查文件是否存在


143

如何检查文件的存在

在模块的文档中,fs有方法的说明fs.exists(path, callback)。但是,据我了解,它只检查目录的存在。而且我需要检查文件

如何才能做到这一点?


3
截至2018年,请使用fs.access('file', err => err ? 'does not exist' : 'exists'),请参阅fs.access
mb21的mb21

Answers:


227

为什么不尝试打开文件?fs.open('YourFile', 'a', function (err, fd) { ... }) 无论如何,经过一分钟的搜索尝试:

var path = require('path'); 

path.exists('foo.txt', function(exists) { 
  if (exists) { 
    // do something 
  } 
}); 

// or 

if (path.existsSync('foo.txt')) { 
  // do something 
} 

对于Node.js v0.12.x及更高版本

双方path.existsfs.exists已弃用

*编辑:

已更改: else if(err.code == 'ENOENT')

至: else if(err.code === 'ENOENT')

林特抱怨双重等于不是三次等于。

使用fs.stat:

fs.stat('foo.txt', function(err, stat) {
    if(err == null) {
        console.log('File exists');
    } else if(err.code === 'ENOENT') {
        // file does not exist
        fs.writeFile('log.txt', 'Some log\n');
    } else {
        console.log('Some other error: ', err.code);
    }
});

1
但是,事实证明,它也可以fs.exists工作。我对该文件的权限有问题。
RomanGorbatko

11
path.exists实际上已被弃用fs.exists
Arnaud Rinquin

42
现在阅读此文档的任何人(Node.js v0.12.x)都请记住这一点,fs.exists并且fs.existsSync也已弃用。fs.stat如上所示,检查文件存在的最佳方法是。
Antrikshy

8
从Node js文档看来,如果计划在检查文件存在后打开文件,最好的方法是实际打开文件并处理错误(如果文件不存在)。因为您的文件可以在存在的检查和打开的功能之间删除...
newprog

6
@Antrikshy fs.existsSync不再被描述,尽管fs.exists仍然如此。
RyanZim

52

同步执行此操作的简便方法。

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

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


12
fs.existsSync(path)现在已弃用,请参阅nodejs.org/api/fs.html#fs_fs_existssync_path。对于同步实施fs.statSync(path)建议,请参阅我的答案。
lmeurs

20
@Imeurs,但nodejs.org/api/fs.html#fs_fs_existssync_path表示:请注意,不建议使用fs.exists(),但不建议使用fs.existsSync()。
HaveF

9
fs.existsSync已被弃用,但现在不再存在。
RyanZim '17

44

编辑: 由于节点,v10.0.0我们可以使用fs.promises.access(...)

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

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

stat的替代方法可能是使用new 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.logfile exists: ${bool}´))

扩展Promise方式:

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

1
提议,这绝对是检测Node.js中是否存在文件的最现代的(2018)方法
AKMorris

1
是的,这是官方推荐的方法,可以简单地检查文件是否存在并且不希望随后进行操作。否则,请使用打开/写入/读取并处理错误。nodejs.org/api/fs.html#fs_fs_stat_path_callback
贾斯汀

1
在我找到的文档fs.constants.F_OK等中,是否也可以像这样访问它们fs.F_OK?奇怪的。还简洁,这很好。
samson '18

1
可以尝试将其fs.promises.access(path, fs.constants.F_OK);简单地设置为Promise而不是创建Promise。
Jeremy Trpka

18

fs.exists(path, callback)并且fs.existsSync(path)现在已弃用,请参见https://nodejs.org/api/fs.html#fs_fs_exists_path_callbackhttps://nodejs.org/api/fs.html#fs_fs_existssync_path

要同步测试文件的存在,可以使用ie。fs.statSync(path)fs.Stats如果文件存在,则将返回一个对象,请参见https://nodejs.org/api/fs.html#fs_class_fs_stats,否则将引发一个错误,该错误将由try / catch语句捕获。

var fs = require('fs'),
  path = '/path/to/my/file',
  stats;

try {
  stats = fs.statSync(path);
  console.log("File exists.");
}
catch (e) {
  console.log("File does not exist.");
}

10
您为fs.existsync提供的链接清楚地表明未弃用该链接“请注意,已弃用fs.exists(),但未弃用fs.existsSync()。(fs.exists()的回调参数接受不一致的参数与其他的Node.js回调fs.existsSync()不使用回调)。”
shreddish

第一个(从顶部开始)答案,其中提到fs变量的来源
Dmitry Korolyov

在撰写此答案时,该信息是正确的。但是,fs.existsSync()不再被弃用。
RyanZim '17

12

V6之前的旧版本: 这是文档

  const fs = require('fs');    
  fs.exists('/etc/passwd', (exists) => {
     console.log(exists ? 'it\'s there' : 'no passwd!');
  });
// or Sync

  if (fs.existsSync('/etc/passwd')) {
    console.log('it\'s there');
  }

更新

V6中的新版本:的文档fs.stat

fs.stat('/etc/passwd', function(err, stat) {
    if(err == null) {
        //Exist
    } else if(err.code == 'ENOENT') {
        // NO exist
    } 
});

1
双方fs.existsfs.existsSync根据您分享的链接已过时。
安迪

existsSync未按照该文档弃用,可能是您阅读该文档时所用。
达尔潘'18

11

现代的异步/等待方式(Node 12.8.x)

const fileExists = async path => !!(await fs.promises.stat(path).catch(e => false));

const main = async () => {
    console.log(await fileExists('/path/myfile.txt'));
}

main();

我们需要使用,fs.stat() or fs.access()因为fs.exists(path, callback)现在不推荐使用

另一个好方法是fs-extra


7

fs.exists从1.0.0版本开始不推荐使用。您可以fs.stat代替使用。

var fs = require('fs');
fs.stat(path, (err, stats) => {
if ( !stats.isFile(filename) ) { // do this 
}  
else { // do this 
}});

这是文档fs.stats的链接


stats.isFile()不需要filename
Wtower

6

@Fox:很好的答案!这里是一些其他选项的扩展。这是我最近一直在使用的解决方案:

var fs = require('fs');

fs.lstat( targetPath, function (err, inodeStatus) {
  if (err) {

    // file does not exist-
    if (err.code === 'ENOENT' ) {
      console.log('No file or directory at',targetPath);
      return;
    }

    // miscellaneous error (e.g. permissions)
    console.error(err);
    return;
  }


  // Check if this is a file or directory
  var isDirectory = inodeStatus.isDirectory();


  // Get file size
  //
  // NOTE: this won't work recursively for directories-- see:
  // http://stackoverflow.com/a/7550430/486547
  //
  var sizeInBytes = inodeStatus.size;

  console.log(
    (isDirectory ? 'Folder' : 'File'),
    'at',targetPath,
    'is',sizeInBytes,'bytes.'
  );


}

PS签出fs-extra(如果您尚未使用它的话)-非常不错。 https://github.com/jprichardson/node-fs-extra



3

async/awaitutil.promisify从节点8开始使用的版本:

const fs = require('fs');
const { promisify } = require('util');
const stat = promisify(fs.stat);

describe('async stat', () => {
  it('should not throw if file does exist', async () => {
    try {
      const stats = await stat(path.join('path', 'to', 'existingfile.txt'));
      assert.notEqual(stats, null);
    } catch (err) {
      // shouldn't happen
    }
  });
});

describe('async stat', () => {
  it('should throw if file does not exist', async () => {
    try {
      const stats = await stat(path.join('path', 'to', 'not', 'existingfile.txt'));
    } catch (err) {
      assert.notEqual(err, null);
    }
  });
});

2
  fs.statSync(path, function(err, stat){
      if(err == null) {
          console.log('File exists');
          //code when all ok
      }else if (err.code == "ENOENT") {
        //file doesn't exist
        console.log('not file');

      }
      else {
        console.log('Some other error: ', err.code);
      }
    });

2

经过一些实验,我发现以下示例使用 fs.stat是异步检查文件是否存在的好方法。它还会检查您的“文件”是否为“确实是文件”(而不是目录)。

假设您正在使用异步代码库,则此方法使用Promises:

const fileExists = path => {
  return new Promise((resolve, reject) => {
    try {
      fs.stat(path, (error, file) => {
        if (!error && file.isFile()) {
          return resolve(true);
        }

        if (error && error.code === 'ENOENT') {
          return resolve(false);
        }
      });
    } catch (err) {
      reject(err);
    }
  });
};

如果文件不存在,则诺言仍然会解决,尽管false。如果文件确实存在,并且是目录,则为resolves true。尝试读取文件的任何错误将reject承诺错误本身。



0

在过去的日子里,我总是先检查一下椅子是否在那儿,然后再坐下来,否则我会有其他选择,比如坐在教练上。现在,node.js网站建议就去(无需检查),答案看起来像这样:

    fs.readFile( '/foo.txt', function( err, data )
    {
      if(err) 
      {
        if( err.code === 'ENOENT' )
        {
            console.log( 'File Doesn\'t Exist' );
            return;
        }
        if( err.code === 'EACCES' )
        {
            console.log( 'No Permission' );
            return;
        }       
        console.log( 'Unknown Error' );
        return;
      }
      console.log( data );
    } );

代码取自2014年3月的http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/,并进行了略微修改以适合计算机。它还会检查权限-删除测试权限chmod a-r foo.txt


0

Vannilla Node.js回调

function fileExists(path, cb){
  return fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result)) //F_OK checks if file is visible, is default does no need to be specified.
}

文件说,你应该使用access()一个替代过时exists()

具有内置Promise的Node.js(节点7+)

function fileExists(path, cb){
  return new Promise((accept,deny) => 
    fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result))
  );
}

流行的JavaScript框架

fs-extra

var fs = require('fs-extra')
await fs.pathExists(filepath)

如您所见,简单得多。与promisify相比,优点是您可以使用此软件包进行完整的输入(完整的intellisense / typescript)!大多数情况下,您已经包含了此库,因为(+ -10.000)其他库依赖于此库。


0

您可以fs.stat用来检查目标是文件还是目录,也可以fs.access用来检查是否可以写/读/执行文件。(请记住使用path.resolve获取目标的完整路径)

说明文件:

完整示例(TypeScript)

import * as fs from 'fs';
import * as path from 'path';

const targetPath = path.resolve(process.argv[2]);

function statExists(checkPath): Promise<fs.Stats> {
  return new Promise((resolve) => {
    fs.stat(checkPath, (err, result) => {
      if (err) {
        return resolve(undefined);
      }

      return resolve(result);
    });
  });
}

function checkAccess(checkPath: string, mode: number = fs.constants.F_OK): Promise<boolean> {
  return new Promise((resolve) => {
    fs.access(checkPath, mode, (err) => {
      resolve(!err);
    });
  });
}

(async function () {
  const result = await statExists(targetPath);
  const accessResult = await checkAccess(targetPath, fs.constants.F_OK);
  const readResult = await checkAccess(targetPath, fs.constants.R_OK);
  const writeResult = await checkAccess(targetPath, fs.constants.W_OK);
  const executeResult = await checkAccess(targetPath, fs.constants.X_OK);
  const allAccessResult = await checkAccess(targetPath, fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK | fs.constants.X_OK);

  if (result) {
    console.group('stat');
    console.log('isFile: ', result.isFile());
    console.log('isDir: ', result.isDirectory());
    console.groupEnd();
  }
  else {
    console.log('file/dir does not exist');
  }

  console.group('access');
  console.log('access:', accessResult);
  console.log('read access:', readResult);
  console.log('write access:', writeResult);
  console.log('execute access:', executeResult);
  console.log('all (combined) access:', allAccessResult);
  console.groupEnd();

  process.exit(0);
}());

0

对于异步版本!并带有承诺版本!这里干净的简单方法!

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

上面的示例仅用于演示!我本可以使用读取流的错误事件!赶上任何错误!并跳过两个电话!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.