[英]Node.js check if file exists
How do I check for the existence of a file?如何检查文件是否存在?
Consider opening the file directly, to avoid race conditions:考虑直接打开文件,以避免竞争条件:
const fs = require('fs');
fs.open('foo.txt', 'r', function (err, fd) {
// ...
});
Using fs.existsSync
:使用
fs.existsSync
:
if (fs.existsSync('foo.txt')) {
// ...
}
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);
}
});
fs.exists
is deprecated. fs.exists
已弃用。
Using path.exists
:使用
path.exists
:
const path = require('path');
path.exists('foo.txt', function(exists) {
if (exists) {
// ...
}
});
Using path.existsSync
:使用
path.existsSync
:
if (path.existsSync('foo.txt')) {
// ...
}
Edit: Since node v10.0.0
we could use fs.promises.access(...)
编辑:由于节点
v10.0.0
我们可以使用fs.promises.access(...)
Example async code that checks if file exists:检查文件是否存在的示例异步代码:
function checkFileExists(file) {
return fs.promises.access(file, fs.constants.F_OK)
.then(() => true)
.catch(() => false)
}
An alternative for stat might be using the new fs.access(...)
: stat 的替代方法可能是使用新的
fs.access(...)
:
minified short promise function for checking:用于检查的缩小的短承诺功能:
s => new Promise(r=>fs.access(s, fs.constants.F_OK, e => r(!e)))
Sample usage:示例用法:
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}´))
expanded Promise way:扩展承诺方式:
// 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);
});
});
}
or if you wanna do it synchronously:或者如果你想同步做:
function checkFileExistsSync(filepath){
let flag = true;
try{
fs.accessSync(filepath, fs.constants.F_OK);
}catch(e){
flag = false;
}
return flag;
}
A easier way to do this synchronously.同步执行此操作的更简单方法。
if (fs.existsSync('/etc/file')) {
console.log('Found file');
}
The API doc says how existsSync
work: API 文档说明了
existsSync
的工作原理:
Test whether or not the given path exists by checking with the file system.通过检查文件系统来测试给定路径是否存在。
Modern async/await way ( Node 12.8.x )现代异步/等待方式(节点 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();
We need to use fs.stat() or fs.access()
because fs.exists(path, callback)
now is deprecated我们需要使用
fs.stat() or fs.access()
因为fs.exists(path, callback)
现在已被弃用
fs.exists(path, callback)
and fs.existsSync(path)
are deprecated now, see https://nodejs.org/api/fs.html#fs_fs_exists_path_callback and https://nodejs.org/api/fs.html#fs_fs_existssync_path . fs.exists(path, callback)
和fs.existsSync(path)
现在已弃用,请参阅https://nodejs.org/api/fs.html#fs_fs_exists_path_callback和https://nodejs.org/api/fs.html# fs_fs_existssync_path 。
To test the existence of a file synchronously one can use ie.要同步测试文件的存在,可以使用 ie。
fs.statSync(path)
. fs.statSync(path)
。 An fs.Stats
object will be returned if the file exists, see https://nodejs.org/api/fs.html#fs_class_fs_stats , otherwise an error is thrown which will be catched by the try / catch statement.如果文件存在,将返回一个
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.");
}
Old Version before V6: here's the documentation 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');
}
UPDATE更新
New versions from V6: documentation for fs.stat
V6 的新版本:
fs.stat
的文档
fs.stat('/etc/passwd', function(err, stat) {
if(err == null) {
//Exist
} else if(err.code == 'ENOENT') {
// NO exist
}
});
Aug 2021 2021 年 8 月
After reading all posts:看完所有帖子后:
let filePath = "./directory1/file1.txt";
if (fs.existsSync(filePath)) {
console.log("The file exists");
} else {
console.log("The file does not exist");
}
There are a lot of inaccurate comments about fs.existsSync()
being deprecated;有很多关于
fs.existsSync()
被弃用的不准确评论; it is not.它不是。
https://nodejs.org/api/fs.html#fs_fs_existssync_path https://nodejs.org/api/fs.html#fs_fs_existssync_path
Note that fs.exists() is deprecated, but fs.existsSync() is not.
请注意,不推荐使用 fs.exists(),但不推荐使用 fs.existsSync()。
@Fox: great answer! @Fox:很好的答案! Here's a bit of an extension with some more options.
这是一个带有更多选项的扩展。 It's what I've been using lately as a go-to solution:
这是我最近一直使用的首选解决方案:
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 check out fs-extra if you aren't already using it-- it's pretty sweet. PS 如果您还没有使用它,请查看 fs-extra——它非常棒。 https://github.com/jprichardson/node-fs-extra )
https://github.com/jprichardson/node-fs-extra )
fs.exists
has been deprecated since 1.0.0. fs.exists
自 1.0.0 起已被弃用。 You can use fs.stat
instead of that.您可以使用
fs.stat
来代替。
var fs = require('fs');
fs.stat(path, (err, stats) => {
if ( !stats.isFile(filename) ) { // do this
}
else { // do this
}});
Here is the link for the documentation fs.stats这是文档fs.stats的链接
async/await
version using util.promisify
as of Node 8:从 Node 8 开始使用
util.promisify
的async/await
版本:
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);
}
});
});
A concise solution in async await style:异步等待风格的简洁解决方案:
import { stat } from 'fs/promises';
const exists = await stat('foo.txt')
.then(() => true)
.catch(() => false);
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);
}
});
After a bit of experimentation, I found the following example using fs.stat
to be a good way to asynchronously check whether a file exists.经过一番实验,我发现以下使用
fs.stat
的示例是异步检查文件是否存在的好方法。 It also checks that your "file" is "really-is-a-file" (and not a directory).它还会检查您的“文件”是否是“真正的文件”(而不是目录)。
This method uses Promises, assuming that you are working with an asynchronous codebase:此方法使用 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);
}
});
};
If the file does not exist, the promise still resolves, albeit false
.如果文件不存在,promise 仍然会解析,尽管是
false
。 If the file does exist, and it is a directory, then is resolves true
.如果文件确实存在,并且它是一个目录,那么 is 解析为
true
。 Any errors attempting to read the file will reject
the promise the error itself.任何试图读取文件的错误都会
reject
错误本身的承诺。
Well I did it this way, as seen on https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback好吧,我是这样做的,如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');
}
});
Is there any problem with this?这有什么问题吗?
Using typescript and fs/promises in node14在 node14 中使用 typescript 和 fs/promises
import * as fsp from 'fs/promises';
try{
const = await fsp.readFile(fullFileName)
...
} catch(e) { ...}
It is better to use fsp.readFile
than fsp.stat
or fsp.access
for two reasons:使用
fsp.readFile
比使用fsp.stat
或fsp.access
更好,原因有二:
fsp.stat
and fsp.readFile
would give different answers. fsp.stat
和fsp.readFile
可能会给出不同的答案。 Either due to subtle differences in the questions they ask, or because the files status changed between the calls.in old days before sit down I always check if chair is there then I sit else I have an alternative plan like sit on a coach.在过去,在坐下之前,我总是检查椅子是否在那里,然后我就坐,否则我有一个替代计划,比如坐在教练上。 Now node.js site suggest just go (no needs to check) and the answer looks like this:
现在 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 );
} );
code taken from http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ from March 2014, and slightly modified to fit computer.代码取自 2014 年 3 月的http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/ ,稍作修改以适应计算机。 It checks for permission as well - remove permission for to test
chmod ar foo.txt
它也会检查权限 - 删除测试
chmod ar foo.txt
的权限
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.
}
the docs say you should use access()
as a replacement for deprecated exists()
文档说您应该使用
access()
代替不推荐使用的exists()
function fileExists(path, cb){
return new Promise((accept,deny) =>
fs.access(path, fs.constants.F_OK,(er, result)=> cb(!err && result))
);
}
var fs = require('fs-extra')
await fs.pathExists(filepath)
As you see much simpler.如您所见,要简单得多。 And the advantage over promisify is that you have complete typings with this package (complete intellisense/typescript)!
与 promisify 相比的优势在于,您可以使用这个包进行完整的输入(完整的智能感知/打字稿)! Most of the cases you will have already included this library because (+-10.000) other libraries depend on it.
大多数情况下,您已经包含了这个库,因为 (+-10.000) 其他库依赖于它。
You can use fs.stat
to check if target is a file or directory and you can use fs.access
to check if you can write/read/execute the file.您可以使用
fs.stat
检查目标是文件还是目录,并且可以使用fs.access
检查是否可以写入/读取/执行文件。 (remember to use path.resolve
to get full path for the target) (记得使用
path.resolve
来获取目标的完整路径)
Documentation:文档:
Full example (TypeScript)完整示例(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);
}());
For asynchronous version!对于异步版本! And with the promise version!
并带有承诺版本! Here the clean simple way!
这里是干净简单的方法!
try {
await fsPromise.stat(filePath);
/**
* File exists!
*/
// do something
} catch (err) {
if (err.code = 'ENOENT') {
/**
* File not found
*/
} else {
// Another error!
}
}
A more practical snippet from my code to illustrate better:我的代码中更实用的片段可以更好地说明:
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
}
};
}
}
The example above is just for demonstration!上面的例子只是为了演示! I could have used the error event of the read stream!
我本可以使用读取流的错误事件! To catch any errors!
捕捉任何错误! And skip the two calls!
跳过这两个电话!
For those who ❤️ async-await对于那些 ❤️ async-await 的人
import fsp from 'fs/promises';
async function isFileExist(path) {
try {
return (await fsp.stat(path)).isFile();
} catch (e) {
return false;
}
}
const path = './dir/file.pdf';
console.log(await isFileExist(path));
Using Promise使用 Promise
import { existsSync } from 'fs'
const exists = (filepath) => new Promise((res) => {
existsSync(filepath) ? res(true) : res(false)
})
// Usage #1 (async/await)
const doesItExist = await exists('foo.txt')
if (doesItExist == false) {
// create the file
}
// Usage #2 (thenable)
exists('foo.txt').then(doesItExist => {
if (!doesItExist) {
// create file
}
})
But honestly it's rare to have a case like that,但老实说,这种情况很少见,
Usually you'll just go with通常你只需要 go
import { existsSync as exists } from 'fs'
if (exists('foo.txt')) {
// do something
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.