- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在文档中它显示了 readdir 的两个版本和 stat 。两者都有异步和同步版本 readir/readdirSync
和 stat/statSync
。
因为 readidir
和 stat
是异步的,我希望它们返回一个 Promise,但是当尝试使用 async/await
时,脚本不会等待对于 readdir
进行解析,如果我使用 .then/.catch
,我会收到错误 cannot read .then of undefined
。
我在这里要做的就是将运行脚本的目录中存在的目录映射到 dirsOfCurrentDir
映射。
无法读取未定义的.then
const fs = require('fs');
const directory = `${ __dirname }/${ process.argv[2] }`;
const dirsOfCurrentDir = new Map();
fs.readdir(directory, (err, files) => {
let path;
if (err)
return console.log(err);
files.forEach(file => {
path = directory + file;
fs.stat(path, (err, stats) => {
if (err)
return console.log(err);
dirsOfCurrentDir.set(file, directory);
});
});
}).then(() => console.log('adasdasd'))
console.log(dirsOfCurrentDir)
map {}
const foo = async () => {
await fs.readdir(directory, (err, files) => {
let path;
if (err)
return console.log(err);
files.forEach(file => {
path = directory + file;
fs.stat(path, (err, stats) => {
if (err)
return console.log(err);
dirsOfCurrentDir.set(file, directory);
});
});
});
};
foo()
console.log(dirsOfCurrentDir)
我最终选择了这两个函数的同步版本:readdirSync
和 statSync
。虽然使用 async 方法或 promisify 会感觉更好,但我仍然没有弄清楚如何使用这两种方法让我的代码正常工作。
const fs = require('fs');
const directory = `${ __dirname }/${ process.argv[2] }`;
const dirsOfCurrentDir = new Map();
const dirContents = fs.readdirSync(directory);
dirContents.forEach(file => {
const path = directory + file;
const stats = fs.statSync(path);
if (stats.isDirectory())
dirsOfCurrentDir.set(file, path);
});
console.log(dirsOfCurrentDir); // logs out the map with all properties set
最佳答案
Because readidir and stat are async I would expect them to return a Promise
首先,请确保您了解异步函数和 async
函数之间的区别。使用 Javascript 中的特定关键字声明为 async
的函数,例如:
async function foo() {
...
}
总是返回一个 promise (根据使用async
关键字声明的函数的定义)。
但是诸如 fs.readdir()
之类的异步函数可能会也可能不会返回 Promise,具体取决于其内部设计。在这种特殊情况下,node.js 中 fs
模块的原始实现仅使用回调,而不使用 Promise(其设计早于 Node.js 中 Promise 的存在)。它的函数是异步的,但没有声明为异步,因此它使用常规回调,而不是 promise 。
因此,您必须使用回调或“promisify”接口(interface)将其转换为返回 promise 的内容,以便您可以使用 await
。
有一个experimental interface in node.js v10为 fs 模块提供内置的 Promise。
const fsp = require('fs').promises;
fsp.readdir(...).then(...)
<小时/>
在早期版本的 Node.js 中,有很多用于 promise 功能的选项。您可以使用util.promisify()逐个功能来完成它:
const promisify = require('util').promisify;
const readdirP = promisify(fs.readdir);
const statP = promisify(fs.stat);
<小时/>
由于我还没有在 Node v10 上进行开发,所以我经常使用 Bluebird Promise 库并一次性 Promisify 整个 fs 库:
const Promise = require('bluebird');
const fs = Promise.promisifyAll(require('fs'));
fs.readdirAsync(...).then(...)
<小时/>
要仅列出给定目录中的子目录,您可以这样做:
const fs = require('fs');
const path = require('path');
const promisify = require('util').promisify;
const readdirP = promisify(fs.readdir);
const statP = promisify(fs.stat);
const root = path.join(__dirname, process.argv[2]);
// utility function for sequencing through an array asynchronously
function sequence(arr, fn) {
return arr.reduce((p, item) => {
return p.then(() => {
return fn(item);
});
}, Promise.resolve());
}
function listDirs(rootDir) {
const dirsOfCurrentDir = new Map();
return readdirP(rootDir).then(files => {
return sequence(files, f => {
let fullPath = path.join(rootDir, f);
return statP(fullPath).then(stats => {
if (stats.isDirectory()) {
dirsOfCurrentDir.set(f, rootDir)
}
});
});
}).then(() => {
return dirsOfCurrentDir;
});
}
listDirs(root).then(m => {
for (let [f, dir] of m) {
console.log(f);
}
});
<小时/>
下面是一个更通用的实现,它列出了文件,并提供了几个关于列出内容和如何呈现结果的选项:
const fs = require('fs');
const path = require('path');
const promisify = require('util').promisify;
const readdirP = promisify(fs.readdir);
const statP = promisify(fs.stat);
const root = path.join(__dirname, process.argv[2]);
// options takes the following:
// recurse: true | false - set to true if you want to recurse into directories (default false)
// includeDirs: true | false - set to true if you want directory names in the array of results
// sort: true | false - set to true if you want filenames sorted in alpha order
// results: can have any one of the following values
// "arrayOfFilePaths" - return an array of full file path strings for files only (no directories included in results)
// "arrayOfObjects" - return an array of objects {filename: "foo.html", rootdir: "//root/whatever", full: "//root/whatever/foo.html"}
// results are breadth first
// utility function for sequencing through an array asynchronously
function sequence(arr, fn) {
return arr.reduce((p, item) => {
return p.then(() => {
return fn(item);
});
}, Promise.resolve());
}
function listFiles(rootDir, opts = {}, results = []) {
let options = Object.assign({recurse: false, results: "arrayOfFilePaths", includeDirs: false, sort: false}, opts);
function runFiles(rootDir, options, results) {
return readdirP(rootDir).then(files => {
let localDirs = [];
if (options.sort) {
files.sort();
}
return sequence(files, fname => {
let fullPath = path.join(rootDir, fname);
return statP(fullPath).then(stats => {
// if directory, save it until after the files so the resulting array is breadth first
if (stats.isDirectory()) {
localDirs.push({name: fname, root: rootDir, full: fullPath, isDir: true});
} else {
results.push({name: fname, root: rootDir, full: fullPath, isDir: false});
}
});
}).then(() => {
// now process directories
if (options.recurse) {
return sequence(localDirs, obj => {
// add directory to results in place right before its files
if (options.includeDirs) {
results.push(obj);
}
return runFiles(obj.full, options, results);
});
} else {
// add directories to the results (after all files)
if (options.includeDirs) {
results.push(...localDirs);
}
}
});
});
}
return runFiles(rootDir, options, results).then(() => {
// post process results based on options
if (options.results === "arrayOfFilePaths") {
return results.map(item => item.full);
} else {
return results;
}
});
}
// get flat array of file paths,
// recursing into directories,
// each directory sorted separately
listFiles(root, {recurse: true, results: "arrayOfFilePaths", sort: true, includeDirs: false}).then(list => {
for (const f of list) {
console.log(f);
}
}).catch(err => {
console.log(err);
});
您可以将此代码复制到文件中并运行它,传递 .
作为参数来列出脚本的目录或您想要列出的任何子目录名称。
如果您想要更少的选项(例如不递归或不保留目录顺序),则可以显着减少此代码,并且可能会更快一些(并行运行一些异步操作)。
关于node.js - NodeJS : Confusion about async "readdir" and "stat",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51180577/
DIR *dir_ptr; struct dirent *dir_entery; dir_ptr = opendir("/tmp"); while (dir_ptr&&(dir_entery = re
我惊讶地发现手册页中包含 readdir 的两个冲突变体的条目。 在 READDIR(2) 中,它特别指出你不想使用它: This is not the function you are intere
我在 Julia 1.7 的 readdir 上使用 isdir 过滤器时遇到了一些问题。运行以下命令: println(readdir("data/")) println(isdir("data/S
我有一个当前正在使用 while 循环处理的目录。文件名实际上是这样的日期: updates.20130831.1445.hr updates.20140831.1445.hr updates.201
int indent = 0; int listDir(const char* dirname){ DIR* dir; struct dirent* d; if(!(dir =
我使用以下代码循环遍历目录以打印出文件的名称。但是,并未显示所有文件。我尝试过使用 clearstatcache 但没有效果。 $str = ''; $ignore = array('
我使用以下代码循环遍历目录以打印出文件的名称。但是,并未显示所有文件。我尝试过使用 clearstatcache 但没有效果。 $str = ''; $ignore = array('
到目前为止,我知道在 Perl 中打开和读取目录的两种方法。您可以使用 opendir、readdir 和 closedir 或者您可以简单地使用 glob 来获取目录的内容。 示例: 使用 op
我正在编写一个点文件存储库管理器,但删除存储库的命令不起作用。它转到存储库文件夹,然后它必须列出所有文件和目录,以便我能够删除它们。问题是,它列出了我需要删除的每个文件或目录,但它排除了非空的 .gi
使用server and client代码。我尝试添加通过 readdir() 实现的 ls 功能 我的 *connection_handler 看起来像这样: void *connection_ha
我有一个使用 readdir() 的函数。我使用 stat() 来获取有关我作为参数提供的目录中的文件的信息。 folder_name[] is actually the absolute path
这个问题已经有答案了: Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized point
嗨,我正在尝试编写一个使用 readdir 的程序,但我读取的条目未按排序顺序。我还应该寻找什么。 最佳答案 尝试scandir,它可以一次读取整个目录并为您对名称进行排序。 关于c - readdi
在 main 中,我使用 deletefolder() 调用以下函数: void deletefolder(){ struct dirent *next_file; DIR *folder
我有一段相当简单的代码来获取 C++ 目录中的文件列表。令人费解的是,目录中的 135 个文件中只有 68 个最终存储在 vector 文件名中。发生了什么事? DIR* pDIR = opendir
我正在尝试读取和处理目录中的所有文件。 如果只使用 readdir() 并计算目录中的文件数,一切都很好。但是,如果我复制文件名 strcpy() 并传递给不同的函数,readdir() 会在读取 4
所以我循环调用 readdir() 函数并将生成的文件名添加到链表中的新节点。通过设置 file_list = add_file_node() 解决问题后,我遇到了 dir_list 循环在访问目录时
我写了一个简单的图片库脚本女巫检查文件夹并显示文件夹中的所有图像我有代码删除 .和 .. 但它不起作用,我不明白为什么任何帮助都会很棒,因为我是 PHP 中 dir 函数的新手。我在链接周围有灯箱标签
这个问题在这里已经有了答案: List regular files only (without directory) problem (2 个答案) 关闭 10 年前。 我的目标是计算目录中的文件数
这是我希望打印的 Perl 脚本 found执行时: #!/usr/bin/perl use warnings; use strict; use utf8; use Encode; use const
我是一名优秀的程序员,十分优秀!