我试图使用Node.js获取目录中所有文件的名称列表。我希望输出文件名数组。我该怎么做?
当前回答
您可以使用fs.readdir或fs.readderSync方法。fs包含在Node.js核心中,因此不需要安装任何东西。
fs.加法器
const testFolder = './tests/';
const fs = require('fs');
fs.readdir(testFolder, (err, files) => {
files.forEach(file => {
console.log(file);
});
});
fs.readder同步
const testFolder = './tests/';
const fs = require('fs');
fs.readdirSync(testFolder).forEach(file => {
console.log(file);
});
这两种方法的区别在于,第一种方法是异步的,因此您必须提供一个回调函数,该函数将在读取过程结束时执行。
第二个是同步的,它将返回文件名数组,但它将停止代码的任何进一步执行,直到读取过程结束。
其他回答
开箱即用
如果您想要一个具有开箱即用的目录结构的对象,我强烈建议您检查目录树。
假设你有这样的结构:
photos
│ june
│ └── windsurf.jpg
└── january
├── ski.png
└── snowboard.jpg
const dirTree = require("directory-tree");
const tree = dirTree("/path/to/photos");
将返回:
{
path: "photos",
name: "photos",
size: 600,
type: "directory",
children: [
{
path: "photos/june",
name: "june",
size: 400,
type: "directory",
children: [
{
path: "photos/june/windsurf.jpg",
name: "windsurf.jpg",
size: 400,
type: "file",
extension: ".jpg"
}
]
},
{
path: "photos/january",
name: "january",
size: 200,
type: "directory",
children: [
{
path: "photos/january/ski.png",
name: "ski.png",
size: 100,
type: "file",
extension: ".png"
},
{
path: "photos/january/snowboard.jpg",
name: "snowboard.jpg",
size: 100,
type: "file",
extension: ".jpg"
}
]
}
]
}
自定义对象
否则,如果要使用自定义设置创建目录树对象,请查看以下代码段。在这个代码沙盒上可以看到一个活生生的例子。
// my-script.js
const fs = require("fs");
const path = require("path");
const isDirectory = filePath => fs.statSync(filePath).isDirectory();
const isFile = filePath => fs.statSync(filePath).isFile();
const getDirectoryDetails = filePath => {
const dirs = fs.readdirSync(filePath);
return {
dirs: dirs.filter(name => isDirectory(path.join(filePath, name))),
files: dirs.filter(name => isFile(path.join(filePath, name)))
};
};
const getFilesRecursively = (parentPath, currentFolder) => {
const currentFolderPath = path.join(parentPath, currentFolder);
let currentDirectoryDetails = getDirectoryDetails(currentFolderPath);
const final = {
current_dir: currentFolder,
dirs: currentDirectoryDetails.dirs.map(dir =>
getFilesRecursively(currentFolderPath, dir)
),
files: currentDirectoryDetails.files
};
return final;
};
const getAllFiles = relativePath => {
const fullPath = path.join(__dirname, relativePath);
const parentDirectoryPath = path.dirname(fullPath);
const leafDirectory = path.basename(fullPath);
const allFiles = getFilesRecursively(parentDirectoryPath, leafDirectory);
return allFiles;
};
module.exports = { getAllFiles };
然后,您可以简单地执行以下操作:
// another-file.js
const { getAllFiles } = require("path/to/my-script");
const allFiles = getAllFiles("/path/to/my-directory");
我制作了一个节点模块来自动化这个任务:mddir
用法
节点mddir“../relative/path/”
要安装:npm install mddir-g
为当前目录生成markdown:mddir
为任何绝对路径生成:mddir/absolute/path
为相对路径生成:mddir~/Documents/wanywhere。
md文件在您的工作目录中生成。
当前忽略node_modules和.git文件夹。
故障排除
如果您收到错误“node\r:没有这样的文件或目录”,问题是您的操作系统使用不同的行尾,如果不将行尾样式显式设置为Unix,mddir无法解析它们。这通常会影响Windows,但也会影响某些版本的Linux。必须在mddir npm全局bin文件夹中将行结尾设置为Unix样式。
线条末端固定
获取npm-bin文件夹路径:
npm配置获取前缀
Cd到该文件夹
brew安装dos2unix
dos2unix-lib/node_modules/mddir/src/mddir.js
这会将行尾转换为Unix而不是Dos
然后正常运行:node mddir“../relative/path/”。
示例生成的markdown文件结构“directoryList.md”
|-- .bowerrc
|-- .jshintrc
|-- .jshintrc2
|-- Gruntfile.js
|-- README.md
|-- bower.json
|-- karma.conf.js
|-- package.json
|-- app
|-- app.js
|-- db.js
|-- directoryList.md
|-- index.html
|-- mddir.js
|-- routing.js
|-- server.js
|-- _api
|-- api.groups.js
|-- api.posts.js
|-- api.users.js
|-- api.widgets.js
|-- _components
|-- directives
|-- directives.module.js
|-- vendor
|-- directive.draganddrop.js
|-- helpers
|-- helpers.module.js
|-- proprietary
|-- factory.actionDispatcher.js
|-- services
|-- services.cardTemplates.js
|-- services.cards.js
|-- services.groups.js
|-- services.posts.js
|-- services.users.js
|-- services.widgets.js
|-- _mocks
|-- mocks.groups.js
|-- mocks.posts.js
|-- mocks.users.js
|-- mocks.widgets.js
使用npm列表内容模块。它读取给定目录的内容和子内容,并返回文件和文件夹路径列表。
const list = require('list-contents');
list("./dist",(o)=>{
if(o.error) throw o.error;
console.log('Folders: ', o.dirs);
console.log('Files: ', o.files);
});
获取所有分区中的文件
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'))
我从你的问题中假设你不需要目录名,只需要文件。
目录结构示例
animals
├── all.jpg
├── mammals
│ └── cat.jpg
│ └── dog.jpg
└── insects
└── bee.jpg
步行功能
根据这一要点,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"
];