Javascript 如何获取 Node.js 目录中所有文件的名称列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2727167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you get a list of the names of all files present in a directory in Node.js?
提问by resopollution
I'm trying to get a list of the names of all the files present in a directory using Node.js. I want output that is an array of filenames. How can I do this?
我正在尝试使用 Node.js 获取目录中存在的所有文件的名称列表。我想要一个文件名数组的输出。我怎样才能做到这一点?
回答by CMS
You can use the fs.readdiror fs.readdirSyncmethods.
您可以使用fs.readdir或fs.readdirSync方法。
fs.readdir
文件读取目录
const testFolder = './tests/';
const fs = require('fs');
fs.readdir(testFolder, (err, files) => {
files.forEach(file => {
console.log(file);
});
});
fs.readdirSync
fs.readdir同步
const testFolder = './tests/';
const fs = require('fs');
fs.readdirSync(testFolder).forEach(file => {
console.log(file);
});
The difference between the two methods, is that the first one is asynchronous, so you have to provide a callback function that will be executed when the read process ends.
这两种方法的区别在于,第一种方法是异步的,因此您必须提供一个回调函数,该函数将在读取过程结束时执行。
The second is synchronous, it will return the file name array, but it will stop any further execution of your code until the read process ends.
第二个是同步的,它将返回文件名数组,但它将停止任何进一步的代码执行,直到读取过程结束。
回答by KFL
IMO the most convinient way to do such tasks is to use a globtool. Here's a glob packagefor node.js. Install with
IMO 执行此类任务的最方便的方法是使用glob工具。这是node.js的glob 包。安装
npm install glob
Then use wild card to match filenames (example taken from package's website)
然后使用通配符匹配文件名(示例取自包的网站)
var glob = require("glob")
// options is optional
glob("**/*.js", options, function (er, files) {
// files is an array of filenames.
// If the `nonull` option is set, and nothing
// was found, then files is ["**/*.js"]
// er is an error object or null.
})
回答by Ruben Tan
The answer above does not perform a recursive search into the directory though. Here's what I did for a recursive search (using node-walk: npm install walk)
不过,上面的答案并未对目录执行递归搜索。这是我为递归搜索所做的(使用node-walk: npm install walk)
var walk = require('walk');
var files = [];
// Walker options
var walker = walk.walk('./test', { followLinks: false });
walker.on('file', function(root, stat, next) {
// Add this file to the list of files
files.push(root + '/' + stat.name);
next();
});
walker.on('end', function() {
console.log(files);
});
回答by Tito100
Get files in all subdirs
获取所有子目录中的文件
function getFiles (dir, files_){
files_ = files_ || [];
var files = fs.readdirSync(dir);
for (var i in files){
var name = dir + '/' + files[i];
if (fs.statSync(name).isDirectory()){
getFiles(name, files_);
} else {
files_.push(name);
}
}
return files_;
}
console.log(getFiles('path/to/dir'))
回答by Ali
Here's a simple solution using only the native fsand pathmodules:
这是一个仅使用本机fs和path模块的简单解决方案:
// sync version
function walkSync(currentDirPath, callback) {
var fs = require('fs'),
path = require('path');
fs.readdirSync(currentDirPath).forEach(function (name) {
var filePath = path.join(currentDirPath, name);
var stat = fs.statSync(filePath);
if (stat.isFile()) {
callback(filePath, stat);
} else if (stat.isDirectory()) {
walkSync(filePath, callback);
}
});
}
or async version (uses fs.readdirinstead):
或异步版本(fs.readdir改为使用):
// async version with basic error handling
function walk(currentDirPath, callback) {
var fs = require('fs'),
path = require('path');
fs.readdir(currentDirPath, function (err, files) {
if (err) {
throw new Error(err);
}
files.forEach(function (name) {
var filePath = path.join(currentDirPath, name);
var stat = fs.statSync(filePath);
if (stat.isFile()) {
callback(filePath, stat);
} else if (stat.isDirectory()) {
walk(filePath, callback);
}
});
});
}
Then you just call (for sync version):
然后你只需调用(同步版本):
walkSync('path/to/root/dir', function(filePath, stat) {
// do something with "filePath"...
});
or async version:
或异步版本:
walk('path/to/root/dir', function(filePath, stat) {
// do something with "filePath"...
});
The difference is in how node blocks while performing the IO. Given that the API above is the same, you could just use the async version to ensure maximum performance.
不同之处在于节点在执行 IO 时如何阻塞。鉴于上面的 API 是相同的,您可以只使用异步版本来确保最佳性能。
However there is one advantage to using the synchronous version. It is easier to execute some code as soon as the walk is done, as in the next statement after the walk. With the async version, you would need some extra way of knowing when you are done. Perhaps creating a map of all paths first, then enumerating them. For simple build/util scripts (vs high performance web servers) you could use the sync version without causing any damage.
但是,使用同步版本有一个优势。一旦遍历完成,就更容易执行一些代码,就像遍历之后的下一条语句一样。使用异步版本,您需要一些额外的方式来知道何时完成。也许首先创建所有路径的地图,然后枚举它们。对于简单的构建/实用程序脚本(与高性能 Web 服务器相比),您可以使用同步版本而不会造成任何损坏。
回答by bnp887
As of Node v10.10.0, it is possible to use the new withFileTypesoption for fs.readdirand fs.readdirSyncin combination with the dirent.isDirectory()function to filter for filenames in a directory. That looks like this:
从 Node v10.10.0 开始,可以使用新withFileTypes选项fs.readdir并fs.readdirSync与dirent.isDirectory()函数结合使用来过滤目录中的文件名。看起来像这样:
fs.readdirSync('./dirpath', {withFileTypes: true})
.filter(item => !item.isDirectory())
.map(item => item.name)
The returned array is in the form:
返回的数组格式如下:
['file1.txt', 'file2.txt', 'file3.txt']
回答by Evan Carroll
Using Promises with ES7
在 ES7 中使用 Promise
Asynchronous use with mz/fs
与 mz/fs 异步使用
The mzmodule provides promisified versions of the core node library. Using them is simple. First install the library...
该mz模块提供了核心节点库的promisified 版本。使用它们很简单。首先安装库...
npm install mz
Then...
然后...
const fs = require('mz/fs');
fs.readdir('./myDir').then(listing => console.log(listing))
.catch(err => console.error(err));
Alternatively you can write them in asynchronous functions in ES7:
或者,您可以在 ES7 的异步函数中编写它们:
async function myReaddir () {
try {
const file = await fs.readdir('./myDir/');
}
catch (err) { console.error( err ) }
};
Update for recursive listing
更新递归列表
Some of the users have specified a desire to see a recursive listing (though not in the question)... Use fs-promise. It's a thin wrapper around mz.
一些用户表示希望看到递归列表(尽管不在问题中)...使用fs-promise. 它是围绕mz.
npm install fs-promise;
then...
然后...
const fs = require('fs-promise');
fs.walk('./myDir').then(
listing => listing.forEach(file => console.log(file.path))
).catch(err => console.error(err));
回答by Hunan Rostomyan
Dependencies.
依赖性。
var fs = require('fs');
var path = require('path');
Definition.
定义。
// String -> [String]
function fileList(dir) {
return fs.readdirSync(dir).reduce(function(list, file) {
var name = path.join(dir, file);
var isDir = fs.statSync(name).isDirectory();
return list.concat(isDir ? fileList(name) : [name]);
}, []);
}
Usage.
用法。
var DIR = '/usr/local/bin';
// 1. List all files in DIR
fileList(DIR);
// => ['/usr/local/bin/babel', '/usr/local/bin/bower', ...]
// 2. List all file names in DIR
fileList(DIR).map((file) => file.split(path.sep).slice(-1)[0]);
// => ['babel', 'bower', ...]
Please note that fileListis way too optimistic. For anything serious, add some error handling.
请注意,这fileList太乐观了。对于任何严重的情况,请添加一些错误处理。
回答by Tyler Long
non-recursive version
非递归版本
You don't say you want to do it recursively so I assume you only need direct children of the directory.
你不是说你想递归地做,所以我假设你只需要目录的直接子级。
Sample code:
示例代码:
const fs = require('fs');
const path = require('path');
fs.readdirSync('your-directory-path')
.filter((file) => fs.lstatSync(path.join(folder, file)).isFile());
回答by Eduardo Cuomo
Load fs:
负载fs:
const fs = require('fs');
Read files async:
异步读取文件:
fs.readdir('./dir', function (err, files) {
// "files" is an Array with files names
});
Read files sync:
读取文件同步:
var files = fs.readdirSync('./dir');

