res*_*ion 882 javascript directory-listing node.js
我正在尝试使用Node.js获取目录中存在的所有文件的名称列表.我想要输出是一个文件名数组.我怎样才能做到这一点?
CMS*_*CMS 1209
您可以使用fs.readdir或fs.readdirSync方法.
fs.readdir
const testFolder = './tests/';
const fs = require('fs');
fs.readdir(testFolder, (err, files) => {
files.forEach(file => {
console.log(file);
});
});
Run Code Online (Sandbox Code Playgroud)
fs.readdirSync
const testFolder = './tests/';
const fs = require('fs');
fs.readdirSync(testFolder).forEach(file => {
console.log(file);
});
Run Code Online (Sandbox Code Playgroud)
两种方法的区别在于第一种方法是异步的,因此您必须提供一个在读取过程结束时执行的回调函数.
第二个是同步的,它将返回文件名数组,但它将停止进一步执行代码,直到读取过程结束.
KFL*_*KFL 184
IMO最方便的方法就是使用glob工具.这是node.js 的glob包.安装时
npm install glob
Run Code Online (Sandbox Code Playgroud)
然后使用通配符匹配文件名(示例来自包的网站)
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.
})
Run Code Online (Sandbox Code Playgroud)
Rub*_*Tan 176
上面的答案虽然没有对目录进行递归搜索.下面是我做了一个递归搜索(使用节点行走: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);
});
Run Code Online (Sandbox Code Playgroud)
Tit*_*100 85
获取所有子目录中的文件
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'))
Run Code Online (Sandbox Code Playgroud)
Ali*_*Ali 59
这是一个只使用本机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);
}
});
}
Run Code Online (Sandbox Code Playgroud)
或异步版本(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);
}
});
});
}
Run Code Online (Sandbox Code Playgroud)
然后你只需要调用(用于同步版本):
walkSync('path/to/root/dir', function(filePath, stat) {
// do something with "filePath"...
});
Run Code Online (Sandbox Code Playgroud)
或异步版本:
walk('path/to/root/dir', function(filePath, stat) {
// do something with "filePath"...
});
Run Code Online (Sandbox Code Playgroud)
不同之处在于节点在执行IO时的阻塞方式.鉴于上面的API是相同的,您可以使用异步版本来确保最高性能.
但是,使用同步版本有一个优点.步行完成后,执行某些代码会更容易,如步行后的下一个语句.使用异步版本,您需要一些额外的方法来了解何时完成.也许首先创建所有路径的地图,然后枚举它们.对于简单的build/util脚本(与高性能Web服务器相比),您可以使用同步版本而不会造成任何损坏.
Eva*_*oll 23
该mz模块提供了核心节点库的promisified版本.使用它们很简单.首先安装库...
npm install mz
Run Code Online (Sandbox Code Playgroud)
然后...
const fs = require('mz/fs');
fs.readdir('./myDir').then(listing => console.log(listing))
.catch(err => console.error(err));
Run Code Online (Sandbox Code Playgroud)
或者,您可以在ES7中的异步函数中编写它们:
async function myReaddir () {
try {
const file = await fs.readdir('./myDir/');
}
catch (err) { console.error( err ) }
};
Run Code Online (Sandbox Code Playgroud)
一些用户已经指定了查看递归列表的愿望(虽然不在问题中)...使用fs-promise.这是一个薄薄的包装mz.
npm install fs-promise;
Run Code Online (Sandbox Code Playgroud)
然后...
const fs = require('fs-promise');
fs.walk('./myDir').then(
listing => listing.forEach(file => console.log(file.path))
).catch(err => console.error(err));
Run Code Online (Sandbox Code Playgroud)
Hun*_*yan 19
依赖.
var fs = require('fs');
var path = require('path');
Run Code Online (Sandbox Code Playgroud)
定义.
// 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]);
}, []);
}
Run Code Online (Sandbox Code Playgroud)
用法.
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', ...]
Run Code Online (Sandbox Code Playgroud)
请注意,这fileList太乐观了.对于任何严重的,添加一些错误处理.
bnp*_*887 16
从Node v10.10.0开始,可以将new withFileTypes选项用于此功能,fs.readdir并fs.readdirSync与该dirent.isDirectory()功能结合使用以过滤目录中的文件名。看起来像这样:
fs.readdirSync('./dirpath', {withFileTypes: true})
.filter(item => !item.isDirectory())
.map(item => item.name)
Run Code Online (Sandbox Code Playgroud)
返回的数组的形式为:
['file1.txt', 'file2.txt', 'file3.txt']
Run Code Online (Sandbox Code Playgroud)
a.b*_*eri 16
我从你的问题中假设你不想要目录名称,只需要文件。
animals
??? all.jpg
??? mammals
? ??? cat.jpg
? ??? dog.jpg
??? insects
??? bee.jpg
Run Code Online (Sandbox Code Playgroud)
Walk 功能如果您只需要一组文件路径,请使用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), []);
}
Run Code Online (Sandbox Code Playgroud)
async function main() {
console.log(await walk('animals'))
}
Run Code Online (Sandbox Code Playgroud)
[
"/animals/all.jpg",
"/animals/mammals/cat.jpg",
"/animals/mammals/dog.jpg",
"/animals/insects/bee.jpg"
];
Run Code Online (Sandbox Code Playgroud)
aak*_*dev 16
它只有两行代码:
fs=require('fs')
fs.readdir("./img/", (err,filename)=>console.log(filename))
Run Code Online (Sandbox Code Playgroud)
Tyl*_*ong 14
你不是说你想要递归地做,所以我假设你只需要目录的直接子项.
示例代码:
const fs = require('fs');
const path = require('path');
fs.readdirSync('your-directory-path')
.filter((file) => fs.lstatSync(path.join(folder, file)).isFile());
Run Code Online (Sandbox Code Playgroud)
小智 14
如果有人还在搜索这个,我会这样做:
import fs from 'fs';
import path from 'path';
const getAllFiles = dir =>
fs.readdirSync(dir).reduce((files, file) => {
const name = path.join(dir, file);
const isDirectory = fs.statSync(name).isDirectory();
return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name];
}, []);Run Code Online (Sandbox Code Playgroud)
它的工作对我来说非常好
Ces*_*las 13
我的单行代码:
const fs = require("fs")
const path = 'somePath/'
const filesArray = fs.readdirSync(path).filter(file => fs.lstatSync(path+file).isFile())
Run Code Online (Sandbox Code Playgroud)
装载fs:
const fs = require('fs');
Run Code Online (Sandbox Code Playgroud)
读取文件异步:
fs.readdir('./dir', function (err, files) {
// "files" is an Array with files names
});
Run Code Online (Sandbox Code Playgroud)
读取文件同步:
var files = fs.readdirSync('./dir');
Run Code Online (Sandbox Code Playgroud)
小智 8
试试这个,它对我有用
import fs from "fs/promises";
const path = "path/to/folder";
export const readDir = async function readDir(path) {
const files = await fs.readdir(path);
// array of file names
console.log(files);
}
Run Code Online (Sandbox Code Playgroud)
获取sorted文件名。您可以基于特定的过滤结果,extension例如'.txt','.jpg'等等。
import * as fs from 'fs';
import * as Path from 'path';
function getFilenames(path, extension) {
return fs
.readdirSync(path)
.filter(
item =>
fs.statSync(Path.join(path, item)).isFile() &&
(extension === undefined || Path.extname(item) === extension)
)
.sort();
}
Run Code Online (Sandbox Code Playgroud)
这是一个 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
}
Run Code Online (Sandbox Code Playgroud)
如果您想要一个具有开箱即用的目录结构的对象,我强烈建议您检查directory-tree。
假设你有这个结构:
photos
? june
? ??? windsurf.jpg
??? january
??? ski.png
??? snowboard.jpg
Run Code Online (Sandbox Code Playgroud)
photos
? june
? ??? windsurf.jpg
??? january
??? ski.png
??? snowboard.jpg
Run Code Online (Sandbox Code Playgroud)
将返回:
{
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"
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
否则,如果您想使用自定义设置创建目录树对象,请查看以下代码段。在这个代码和框上可以看到一个活生生的例子。
const dirTree = require("directory-tree");
const tree = dirTree("/path/to/photos");
Run Code Online (Sandbox Code Playgroud)
然后你可以简单地做:
{
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"
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
使用平面地图:
\nfunction getFiles(dir) {\n return fs.readdirSync(dir).flatMap((item) => {\n const path = `${dir}/${item}`;\n if (fs.statSync(path).isDirectory()) {\n return getFiles(path);\n }\n\n return path;\n });\n}\nRun Code Online (Sandbox Code Playgroud)\n给定以下目录:
\ndist\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 404.html\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app-AHOLRMYQ.js\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 img\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 demo.gif\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 start.png\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.html\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 sw.js\nRun Code Online (Sandbox Code Playgroud)\n用法:
\ngetFiles("dist")\nRun Code Online (Sandbox Code Playgroud)\n输出:
\n[\n \'dist/404.html\',\n \'dist/app-AHOLRMYQ.js\',\n \'dist/img/demo.gif\',\n \'dist/img/start.png\',\n \'dist/index.html\'\n]\nRun Code Online (Sandbox Code Playgroud)\n
这是一个异步递归版本。
function ( path, callback){
// the callback gets ( err, files) where files is an array of file names
if( typeof callback !== 'function' ) return
var
result = []
, files = [ path.replace( /\/\s*$/, '' ) ]
function traverseFiles (){
if( files.length ) {
var name = files.shift()
fs.stat(name, function( err, stats){
if( err ){
if( err.errno == 34 ) traverseFiles()
// in case there's broken symbolic links or a bad path
// skip file instead of sending error
else callback(err)
}
else if ( stats.isDirectory() ) fs.readdir( name, function( err, files2 ){
if( err ) callback(err)
else {
files = files2
.map( function( file ){ return name + '/' + file } )
.concat( files )
traverseFiles()
}
})
else{
result.push(name)
traverseFiles()
}
})
}
else callback( null, result )
}
traverseFiles()
}
Run Code Online (Sandbox Code Playgroud)
采用@Hunan-Rostomyan 的一般方法,使其更加简洁并增加了excludeDirs论点。用 扩展很简单includeDirs,只需遵循相同的模式:
import * as fs from 'fs';
import * as path from 'path';
function fileList(dir, excludeDirs?) {
return fs.readdirSync(dir).reduce(function (list, file) {
const name = path.join(dir, file);
if (fs.statSync(name).isDirectory()) {
if (excludeDirs && excludeDirs.length) {
excludeDirs = excludeDirs.map(d => path.normalize(d));
const idx = name.indexOf(path.sep);
const directory = name.slice(0, idx === -1 ? name.length : idx);
if (excludeDirs.indexOf(directory) !== -1)
return list;
}
return list.concat(fileList(name, excludeDirs));
}
return list.concat([name]);
}, []);
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
console.log(fileList('.', ['node_modules', 'typings', 'bower_components']));
Run Code Online (Sandbox Code Playgroud)
如果有人,我的 2 美分:
只想从项目的本地子文件夹中列出文件名(不包括目录)
const fs = require("fs");
const path = require("path");
/**
* @param {string} relativeName "resources/foo/goo"
* @return {string[]}
*/
const listFileNames = (relativeName) => {
try {
const folderPath = path.join(process.cwd(), ...relativeName.split("/"));
return fs
.readdirSync(folderPath, { withFileTypes: true })
.filter((dirent) => dirent.isFile())
.map((dirent) => dirent.name.split(".")[0]);
} catch (err) {
// ...
}
};
Run Code Online (Sandbox Code Playgroud)
README.md
package.json
resources
|-- countries
|-- usa.yaml
|-- japan.yaml
|-- gb.yaml
|-- provinces
|-- .........
listFileNames("resources/countries") #=> ["usa", "japan", "gb"]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
806080 次 |
| 最近记录: |