如何捕获fs.readFileSync()没有文件?

Met*_*kin 118 error-handling try-catch node.js

在node.js中,readFile()显示了如何捕获错误,但是没有关于错误处理的readFileSync()函数的注释.因此,如果我在没有文件时尝试使用readFileSync(),我会收到错误Error: ENOENT, no such file or directory.

如何捕获抛出的异常?doco没有说明抛出了什么异常,所以我不知道我需要捕获哪些异常.我应该注意到,我不喜欢通用的'捕获每一个可能的异常'样式的try/catch语句.在这种情况下,我希望捕获文件不存在时发生的特定异常,并尝试执行readFileSync.

请注意,我在启动连接尝试之前只在启动时执行同步功能,因此不需要我不应该使用同步功能的注释:-)

Gol*_*den 187

基本上,fs.readFileSync在找不到文件时会抛出错误.这个错误来自Error原型并抛出使用throw,因此捕获的唯一方法是使用try / catch块:

var fileContents;
try {
  fileContents = fs.readFileSync('foo.bar');
} catch (err) {
  // Here you get the error when the file was not found,
  // but you also get any other error
}
Run Code Online (Sandbox Code Playgroud)

遗憾的是,仅通过查看其原型链,您无法检测到抛出了哪个错误:

if (err instanceof Error)
Run Code Online (Sandbox Code Playgroud)

是你能做的最好的,对大多数(如果不是全部)错误都是如此.因此,我建议你去code酒店,检查它的价值:

if (err.code === 'ENOENT') {
  console.log('File not found!');
} else {
  throw err;
}
Run Code Online (Sandbox Code Playgroud)

这样,您只处理此特定错误并重新抛出所有其他错误.

或者,您也可以访问错误的message属性以验证详细的错误消息,在这种情况下是:

ENOENT, no such file or directory 'foo.bar'
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

  • 对于文件存在但由于缺乏权限而无法读取的情况,还应在 if 语句中检查 `EACCES` 代码 (3认同)

Fra*_*cia 19

虽然接受的解决方案没问题,但我找到了一种更好的处理方法.您可以检查文件是否同步存在:

var file = 'info.json';
var content = '';

// Check that the file exists locally
if(!fs.existsSync(file)) {
  console.log("File not found");
}

// The file *does* exist
else {
  // Read the file and do anything you want
  content = fs.readFileSync(this.local, 'utf-8');
}
Run Code Online (Sandbox Code Playgroud)

  • 根本不是更好.如果在existsSync和readFileSync调用之间从磁盘中删除文件怎么办?你的代码现在有一个等待发生的竞争条件...... (12认同)
  • 竞争条件在出现之前并不重要。像这样的答案就是为什么软件如此充满错误、为什么需要如此频繁地重新启动计算机、为什么存在如此多的安全漏洞等等。Stack Overflow 应该有一个标记来标记可能有害的答案。 (3认同)
  • 我想在这里插话并同意双方的观点。但不同意@tkarls 的黑白描述。例如,我正在编写用于解析磁盘上的 Markdown 文件的代码,这些文件永远不会被删除。在这种情况下,当我知道永远不会出现这种竞争条件时,检查它是否存在比使用 try catch 作为控制流更有意义。软件工程不是一种对与错,而是所有情况下的事情...... (3认同)
  • 现在,fs.existsSync [不再被弃用](https://nodejs.org/api/fs.html#fs_fs_existssync_path):"请注意,fs.exists()已弃用,但fs.existsSync()不是." (2认同)
  • @tkarls是的,这是完全正确的,那是在2015年我还在学习Node.js时编写的,它具有竞争条件。但是,有两点需要注意:这种竞争条件的可能性很小,以至于基本上可以忽略不计;第二种是超级种子,其一是如今我将使用try / catch和async / await来使我的代码更加灵活“其他”异常(因为Node是友好的异常)。 (2认同)

log*_*yth 11

您必须捕获错误,然后检查它是什么类型的错误.

try {
  var data = fs.readFileSync(...)
} catch (err) {
  // If the type is not what you want, then just throw the error again.
  if (err.code !== 'ENOENT') throw err;

  // Handle a file-not-found error
}
Run Code Online (Sandbox Code Playgroud)


sdg*_*sdh 5

对于这些场景,我使用立即调用的 lambda:

const config = (() => {
  try {
    return JSON.parse(fs.readFileSync('config.json'));
  } catch (error) {
    return {};
  }
})();
Run Code Online (Sandbox Code Playgroud)

async 版本:

const config = await (async () => {
  try {
    return JSON.parse(await fs.readFileAsync('config.json'));
  } catch (error) {
    return {};
  }
})();
Run Code Online (Sandbox Code Playgroud)

  • @Metalskin Webpack + Babel。但是,`fs` 是一个 Node 模块 (2认同)