fs.exists(path, callback)


稳定性: 0 - 已弃用:请改用 fs.stat()fs.access()

通过检查文件系统来测试给定 path 处的元素是否存在。然后使用 true 或 false 调用 callback 参数:

【Test whether or not the element at the given path exists by checking with the file system. Then call the callback argument with either true or false:】

import { exists } from 'node:fs';

exists('/etc/passwd', (e) => {
  console.log(e ? 'it exists' : 'no passwd!');
}); 

此回调的参数与其他 Node.js 回调不一致。 通常,Node.js 回调的第一个参数是一个 err 参数,后面可选跟其他参数。fs.exists() 回调只有一个布尔参数。这也是推荐使用 fs.access() 而不是 fs.exists() 的原因之一。

如果 path 是符号链接,则会跟随该链接。因此,如果 path 存在但指向一个不存在的元素,回调将收到值 false

【If path is a symbolic link, it is followed. Thus, if path exists but points to a non-existent element, the callback will receive the value false.】

在调用 fs.open()fs.readFile()fs.writeFile() 之前使用 fs.exists() 来检查文件是否存在是不推荐的。这样做会引入竞争条件,因为在两次调用之间,其他进程可能会更改文件的状态。相反,用户代码应该直接打开/读取/写入文件,并处理文件不存在时引发的错误。

【Using fs.exists() to check for the existence of a file before calling fs.open(), fs.readFile(), or fs.writeFile() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file does not exist.】

写 (不推荐)

import { exists, open, close } from 'node:fs';

exists('myfile', (e) => {
  if (e) {
    console.error('myfile already exists');
  } else {
    open('myfile', 'wx', (err, fd) => {
      if (err) throw err;

      try {
        writeMyData(fd);
      } finally {
        close(fd, (err) => {
          if (err) throw err;
        });
      }
    });
  }
}); 

写(推荐)

import { open, close } from 'node:fs';
open('myfile', 'wx', (err, fd) => {
  if (err) {
    if (err.code === 'EEXIST') {
      console.error('myfile already exists');
      return;
    }

    throw err;
  }

  try {
    writeMyData(fd);
  } finally {
    close(fd, (err) => {
      if (err) throw err;
    });
  }
}); 

阅读(不推荐)

import { open, close, exists } from 'node:fs';

exists('myfile', (e) => {
  if (e) {
    open('myfile', 'r', (err, fd) => {
      if (err) throw err;

      try {
        readMyData(fd);
      } finally {
        close(fd, (err) => {
          if (err) throw err;
        });
      }
    });
  } else {
    console.error('myfile does not exist');
  }
}); 

阅读(推荐)

import { open, close } from 'node:fs';

open('myfile', 'r', (err, fd) => {
  if (err) {
    if (err.code === 'ENOENT') {
      console.error('myfile does not exist');
      return;
    }

    throw err;
  }

  try {
    readMyData(fd);
  } finally {
    close(fd, (err) => {
      if (err) throw err;
    });
  }
}); 

上面“不推荐”的示例先检查文件是否存在,然后再使用文件;“推荐”的示例更好,因为它们直接使用文件,并处理可能出现的错误。

【The "not recommended" examples above check for existence and then use the file; the "recommended" examples are better because they use the file directly and handle the error, if any.】

一般来说,只有在文件不会被直接使用时才检查文件是否存在,例如当文件的存在是来自另一个进程的信号时。

【In general, check for the existence of a file only if the file won't be used directly, for example when its existence is a signal from another process.】