我正在尝试使用Node.js获取目录中所有文件的名称列表。 我希望输出是一个包含文件名的数组。 我该如何实现?
我正在尝试使用Node.js获取目录中所有文件的名称列表。 我希望输出是一个包含文件名的数组。 我该如何实现?
fs.readdir
或fs.readdirSync
方法。fs
已经包含在Node.js核心中,所以不需要安装任何东西。
fs.readdir
const testFolder = './tests/';
const fs = require('fs');
fs.readdir(testFolder, (err, files) => {
files.forEach(file => {
console.log(file);
});
});
fs.readdirSync
const testFolder = './tests/';
const fs = require('fs');
fs.readdirSync(testFolder).forEach(file => {
console.log(file);
});
ls
命令的输出吗?等到有人创建了一些带有空格和换行符的文件名再试试看吧... - Radon Rosborough在我看来,完成这样的任务最方便的方式是使用 glob 工具。这里有一个适用于 node.js 的 glob 包。安装命令如下:
npm install glob
然后使用通配符来匹配文件名(示例取自包的网站)
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.
})
如果您计划使用globby,这里有一个示例可以查找当前文件夹下的任何xml文件。
var globby = require('globby');
const paths = await globby("**/*.xml");
cwd
。 - jcollumglob()
函数外获取结果?例如,我想要在console.log()
中输出结果,但不想在glob()
函数内部输出。 - Lantiglob.sync(pattern, [options])
方法可能更易于使用,因为它仅返回文件名数组,而无需使用回调函数。更多信息请参考:https://github.com/isaacs/node-glob 。 - Glenn Lawrence上面的答案没有进行目录的递归搜索。这是我使用 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);
});
.git
开头的目录。 - j_d从Node v10.10.0开始,可以使用fs.readdir
和fs.readdirSync
的新选项withFileTypes
结合dirent.isDirectory()
函数来过滤目录中的文件名。代码如下:
fs.readdirSync('./dirpath', {withFileTypes: true})
.filter(item => !item.isDirectory())
.map(item => item.name)
返回的数组形式为:['file1.txt', 'file2.txt', 'file3.txt']
const fs=require('fs');
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'))
if (typeof files_ === 'undefined') files_=[];
呢?你只需要写成var files_ = files_ || [];
就可以了,两者的意思是一样的。 - jkutianskigetFiles
的开头添加 var fs = require('fs');
。 - GFoley83这里是一个简单的解决方案,只使用原生 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);
}
});
}
或者异步版本(使用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);
}
});
});
}
然后您只需调用(同步版本):
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是一样的,你可以使用异步版本来保证最大的性能。
然而,使用同步版本有一个优点。在遍历完成后,更容易立即执行某些代码,例如在遍历后面的下一条语句中。对于异步版本,你需要一些额外的方法来知道何时完成操作。或许先创建所有路径的映射表,然后枚举它们。对于简单的构建/实用脚本(与高性能网络服务器相比),你可以使用同步版本而不会造成任何损害。
walk(filePath, callback);
这一行替换为 walkSync(filePath, callback);
。 - MIDE11mz
模块提供了核心node库的Promise封装版本。使用它们非常简单。首先安装该库...
npm install mz
然后...
const fs = require('mz/fs');
fs.readdir('./myDir').then(listing => console.log(listing))
.catch(err => console.error(err));
或者您可以在ES7的异步函数中编写它们:
async function myReaddir () {
try {
const file = await fs.readdir('./myDir/');
}
catch (err) { console.error( err ) }
};
一些用户已经表达了希望看到递归列表的愿望(虽然没有在问题中提出)...使用fs-promise
。它是mz
的一个薄包装器。
npm install fs-promise;
那么...
const fs = require('fs-promise');
fs.walk('./myDir').then(
listing => listing.forEach(file => console.log(file.path))
).catch(err => console.error(err));
您没有说明需要使用递归,因此我假设您只需要目录的直接子级。
示例代码:
const fs = require('fs');
const path = require('path');
fs.readdirSync('your-directory-path')
.filter((file) => fs.lstatSync(path.join(folder, file)).isFile());
依赖关系。
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
过于乐观。对于任何重要的事情,请添加一些错误处理。excludeDirs
数组参数。这使得它有所改变,如果您想要的话,也许您应该编辑它。否则,我会在另一个答案中添加它。https://gist.github.com/AlecTaylor/f3f221b4fb86b4375650 - A T我从你的问题中推断出,你只想要文件名而不是目录名。
animals
├── all.jpg
├── mammals
│ └── cat.jpg
│ └── dog.jpg
└── insects
└── bee.jpg
Walk
函数感谢Justin Maier在这个代码片段中的贡献。
如果您只想要文件路径的数组,请使用return_object: false
:
const fs = require('fs').promises;
const path = require('path');
async function walk(dir) {
let files = await fs.readdir(dir);
files = await Promise.all(files.map(async file => {
const filePath = path.join(dir, file);
const stats = await fs.stat(filePath);
if (stats.isDirectory()) return walk(filePath);
else if(stats.isFile()) return filePath;
}));
return files.reduce((all, folderContents) => all.concat(folderContents), []);
}
async function main() {
console.log(await walk('animals'))
}
[
"/animals/all.jpg",
"/animals/mammals/cat.jpg",
"/animals/mammals/dog.jpg",
"/animals/insects/bee.jpg"
];
[ "/animals/all.jpg", "/animals/mammals" "/animals/mammals/cat.jpg", "/animals/mammals/dog.jpg", "/animals/insects/bee.jpg" ];
有什么解决方案吗? - Aakashreturn
之前添加files.unshift(dir)
。无论如何,最好创建一个新问题,因为它可能有助于其他有相同需求的人并获得更好的反馈。;-) - a.barbierianimals/mammals/name
,我想在提供一些深度后停止在哺乳动物。 [ "/animals/all.jpg", "/animals/mammals/cat.jpg", "/animals/mammals/dog.jpg", "/animals/insects/bee.jpg" ];
- Aakash
fs.readdir
可以工作,但无法使用类似ls /tmp/*core*
的文件名通配符。请查看 https://github.com/isaacs/node-glob。Globs 甚至可以搜索子目录中的文件。 - Jessreaddir-recursive
模块。 - Ethan Davis