我试图使用Node.js获取目录中所有文件的名称列表。我希望输出文件名数组。我该怎么做?
当前回答
从Node v10.10.0开始,可以将fs.readdir和fs.readderSync的新withFileTypes选项与dirent.isDirectory()函数结合使用,以过滤目录中的文件名。看起来像这样:
fs.readdirSync('./dirpath', {withFileTypes: true})
.filter(item => !item.isDirectory())
.map(item => item.name)
返回的数组的格式为:
['file1.txt', 'file2.txt', 'file3.txt']
其他回答
我最近为此开发了一个工具,它可以做到这一点。。。它异步获取目录并返回项目列表。您可以获取目录、文件或两者,首先是文件夹。如果不想获取整个文件夹,也可以对数据进行分页。
https://www.npmjs.com/package/fs-browser
这是链接,希望它能帮助到某人!
依赖关系。
var fs = require('fs');
var path = require('path');
释义
// 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]);
}, []);
}
用法
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', ...]
请注意,fileList过于乐观。对于任何严重的问题,请添加一些错误处理。
function getFilesRecursiveSync(dir, fileList, optionalFilterFunction) {
if (!fileList) {
grunt.log.error("Variable 'fileList' is undefined or NULL.");
return;
}
var files = fs.readdirSync(dir);
for (var i in files) {
if (!files.hasOwnProperty(i)) continue;
var name = dir + '/' + files[i];
if (fs.statSync(name).isDirectory()) {
getFilesRecursiveSync(name, fileList, optionalFilterFunction);
} else {
if (optionalFilterFunction && optionalFilterFunction(name) !== true)
continue;
fileList.push(name);
}
}
}
这是一个TypeScript,可选递归,可选错误日志和异步解决方案。可以为要查找的文件名指定正则表达式。
我使用了fs extra,因为这是对fs的一个简单的超集改进。
import * as FsExtra from 'fs-extra'
/**
* Finds files in the folder that match filePattern, optionally passing back errors .
* If folderDepth isn't specified, only the first level is searched. Otherwise anything up
* to Infinity is supported.
*
* @static
* @param {string} folder The folder to start in.
* @param {string} [filePattern='.*'] A regular expression of the files you want to find.
* @param {(Error[] | undefined)} [errors=undefined]
* @param {number} [folderDepth=0]
* @returns {Promise<string[]>}
* @memberof FileHelper
*/
public static async findFiles(
folder: string,
filePattern: string = '.*',
errors: Error[] | undefined = undefined,
folderDepth: number = 0
): Promise<string[]> {
const results: string[] = []
// Get all files from the folder
let items = await FsExtra.readdir(folder).catch(error => {
if (errors) {
errors.push(error) // Save errors if we wish (e.g. folder perms issues)
}
return results
})
// Go through to the required depth and no further
folderDepth = folderDepth - 1
// Loop through the results, possibly recurse
for (const item of items) {
try {
const fullPath = Path.join(folder, item)
if (
FsExtra.statSync(fullPath).isDirectory() &&
folderDepth > -1)
) {
// Its a folder, recursively get the child folders' files
results.push(
...(await FileHelper.findFiles(fullPath, filePattern, errors, folderDepth))
)
} else {
// Filter by the file name pattern, if there is one
if (filePattern === '.*' || item.search(new RegExp(filePattern, 'i')) > -1) {
results.push(fullPath)
}
}
} catch (error) {
if (errors) {
errors.push(error) // Save errors if we wish
}
}
}
return results
}
下面是一个仅使用本机fs和路径模块的简单解决方案:
// 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);
}
});
}
或异步版本(改用fs.readder):
// 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);
}
});
});
}
然后您只需调用(同步版本):
walkSync('path/to/root/dir', function(filePath, stat) {
// do something with "filePath"...
});
或异步版本:
walk('path/to/root/dir', function(filePath, stat) {
// do something with "filePath"...
});
不同之处在于节点在执行IO时如何阻塞。考虑到上面的API是相同的,您可以只使用异步版本来确保最大性能。
然而,使用同步版本有一个优点。在遍历完成后立即执行一些代码更容易,就像在遍历后的下一条语句中一样。对于异步版本,您需要一些额外的方法来知道何时完成。也许首先创建所有路径的映射,然后枚举它们。对于简单的build/util脚本(与高性能web服务器相比),您可以使用同步版本而不会造成任何损坏。
推荐文章
- Node.js和CPU密集型请求
- val()和text()的区别
- 如何使用Jest测试对象键和值是否相等?
- 将长模板文字行换行为多行,而无需在字符串中创建新行
- 如何在JavaScript中映射/减少/过滤一个集?
- Bower: ENOGIT Git未安装或不在PATH中
- 为什么在节点REPL中没有定义__dirname ?
- 添加javascript选项选择
- 在Node.js中克隆对象
- 为什么在JavaScript的Date构造函数中month参数的范围从0到11 ?
- DOS中的递归目录列表
- 使用JavaScript更改URL参数并指定默认值
- 在window.setTimeout()发生之前取消/终止
- 如何删除未定义和空值从一个对象使用lodash?
- Node.js中的process.env.PORT是什么?