// ES6 version using asynchronous iterators, compatible with node v10.0+ | |
const fs = require("fs"); | |
const path = require("path"); | |
async function* walk(dir) { | |
for await (const d of await fs.promises.opendir(dir)) { | |
const entry = path.join(dir, d.name); | |
if (d.isDirectory()) yield* walk(entry); | |
else if (d.isFile()) yield entry; | |
} | |
} | |
// Then, use it with a simple async for loop | |
async function main() { | |
for await (const p of walk('/tmp/')) | |
console.log(p) | |
} |
// Callback-based version for old versions of Node | |
var fs = require("fs"), | |
path = require("path"); | |
function walk(dir, callback) { | |
fs.readdir(dir, function(err, files) { | |
if (err) throw err; | |
files.forEach(function(file) { | |
var filepath = path.join(dir, file); | |
fs.stat(filepath, function(err,stats) { | |
if (stats.isDirectory()) { | |
walk(filepath, callback); | |
} else if (stats.isFile()) { | |
callback(filepath, stats); | |
} | |
}); | |
}); | |
}); | |
} | |
if (exports) { | |
exports.walk = walk; | |
} else { | |
walk(".", manageFile); | |
} |
This comment has been minimized.
This comment has been minimized.
@jimmylab Use import fs from 'fs';
import path from 'path';
function walk(dir) {
return new Promise((resolve, reject) => {
fs.readdir(dir, (error, files) => {
if (error) {
return reject(error);
}
Promise.all(files.map((file) => {
return new Promise((resolve, reject) => {
const filepath = path.join(dir, file);
fs.stat(filepath, (error, stats) => {
if (error) {
return reject(error);
}
if (stats.isDirectory()) {
walk(filepath).then(resolve);
} else if (stats.isFile()) {
resolve(filepath);
}
});
});
}))
.then((foldersContents) => {
resolve(foldersContents.reduce((all, folderContents) => all.concat(folderContents), []));
});
});
});
} |
This comment has been minimized.
This comment has been minimized.
This is better than npm's walk IMO. Thank you! |
This comment has been minimized.
This comment has been minimized.
Here's an es6 version 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), []);
} |
This comment has been minimized.
This comment has been minimized.
Synchronous version: const walkSync = (dir, callback) => {
const files = fs.readdirSync(dir);
files.forEach((file) => {
var filepath = path.join(dir, file);
const stats = fs.statSync(filepath);
if (stats.isDirectory()) {
walkSync(filepath, callback);
} else if (stats.isFile()) {
callback(filepath, stats);
}
});
}; |
This comment has been minimized.
This comment has been minimized.
I think the best way to do this in modern javascript is with an asynchronous iterator : async function* walk(dir) {
for await (const d of await fs.promises.opendir(dir)) {
const entry = path.join(dir, d.name);
if (d.isDirectory()) yield* await walk(entry);
else if (d.isFile()) yield entry;
}
} The code is both clear, non-blocking, concise, easy to use, and avoids the explicit call to stats. It works in node v10.0+. You then iterate with just for await (const p of walk('/tmp/'))
console.log(p) |
This comment has been minimized.
This comment has been minimized.
@lovasoa I agree. But a useful feature (for me anyway) is to give the callback the ability to stop the process (when the file has been found, or it has gone too deep for example) |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Ah yes, very good point. |
This comment has been minimized.
This comment has been minimized.
I'm just getting started with node so I'm sure the answer is straight forward so forgive me...but if I enter the May 11 code first it won't accept the |
This comment has been minimized.
This comment has been minimized.
I'm not sure I understand that...
I guess you are either using an old version version of node or you are trying to use Here are a few articles you can read to get started :
|
This comment has been minimized.
This comment has been minimized.
I'm using Node 12 according to It just looked like the two parts of the May 11 comment were a standalone I could just run but thanks for the links I'll see if I can work it out! |
This comment has been minimized.
This comment has been minimized.
You can easily turn it into a standalone, just wrap the top-level code in an async function:
Or do it all in one, like:
|
This comment has been minimized.
This comment has been minimized.
I searched for this a lot of time , Thanks ;) |
This comment has been minimized.
Here comes a problem: how can I know when would the traversal stop?