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

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

技术背景

在Node.js开发中,经常需要检查文件或目录是否存在,以此来决定后续的操作,比如读取文件、创建目录等。随着Node.js的发展,检查文件或目录是否存在的方法也发生了变化。

实现步骤

1. 使用fs.existsSync()

这是目前推荐的同步检查文件或目录是否存在的方法。虽然fs.exists()已被弃用,但fs.existsSync()并未被弃用。示例代码如下:

1
2
3
4
const fs = require("fs"); // Or `import fs from "fs";` with ESM
if (fs.existsSync(path)) {
// Do something
}

2. 历史方法回顾

  • 2010年原始方法:使用statSynclstatSync
1
2
3
4
5
6
7
8
9
10
11
12
13
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) {
// ...
}
  • 2012年9月更新:使用fs.existsSyncfs.exists
1
2
3
4
5
6
7
8
9
10
11
12
13
var fs = require('fs');

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

// Or

fs.exists(path, function(exists) {
if (exists) {
// Do something
}
});
  • 2015年2月更新fs.existsSyncfs.exists将被弃用,可能需回到stat相关方法。
  • 2015年12月更新:可使用fs.access(path, fs.F_OK, ...)fs.accessSync(path, fs.F_OK)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
}
});

核心代码

使用fs.existsSync()检查文件或目录是否存在

1
2
3
4
5
6
7
const fs = require("fs");
const path = './test.txt';
if (fs.existsSync(path)) {
console.log('文件或目录存在');
} else {
console.log('文件或目录不存在');
}

使用fs.accessSync()检查文件是否可访问

1
2
3
4
5
6
7
8
const fs = require('fs');
const filePath = './test.txt';
try {
fs.accessSync(filePath, fs.F_OK);
console.log('文件可访问');
} catch (e) {
console.log('文件不可访问');
}

最佳实践

考虑权限问题

在检查文件是否存在时,可能会遇到权限问题。可以编写一个函数来处理这种情况:

1
2
3
4
5
6
7
function fileExists(filePath) {
try {
return fs.statSync(filePath).isFile();
} catch (err) {
return false;
}
}

异步检查

如果可以使用异步检查(通常对于I/O操作是最佳选择),可以使用fs.promises.accessfs.access

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 使用fs.promises.access的异步检查
async function checkFileAsync() {
try {
await fs.promises.access('somefile');
console.log('文件存在');
} catch (error) {
console.log('文件不存在');
}
}

checkFileAsync();

// 使用fs.access的异步检查
fs.access('somefile', error => {
if (!error) {
console.log('文件存在');
} else {
console.log('文件不存在');
}
});

常见问题

权限问题

当遇到权限问题时,fs.statSyncfs.accessSync会抛出错误。在处理这种情况时,需要考虑权限错误并不一定意味着文件存在,可能是缺少对包含该文件的目录的访问权限。

竞态条件

使用fs.exists或在打开文件之前检查文件是否存在是一种反模式,可能会导致竞态条件。因为在检查和打开文件之间,其他进程可能会删除该文件。建议直接打开文件并处理文件不存在的错误。