gpt4 book ai didi

javascript - 递归抓取并以异步方式写入文件

转载 作者:行者123 更新时间:2023-12-02 22:38:24 25 4
gpt4 key购买 nike

我对异步代码完全陌生,所以我现在有点不知所措。

我正在做的是异步递归地抓取存档,以检测给定存档中的文件路径。我想做的是将检测到的所有文件路径写入单个文件。然而,当我执行代码时,它没有将它们正确写入文件。我假设这是由于多次写入同时发生所致。

之前的data.json

{
"K": {
"files": []
}
}

data.json 之后

{
"K": {
"files": [
{
"name": "Testing.txt",
"bytes": 1648,
"path": "K:\\Texts\\Testing.txt"
}
]
}
} }
]
}
}
}.txt"
}
]
}
} }
]
}
}

我显然可以同步编写代码,但为了提高效率,我更愿意异步完成所有这些工作。尽管如此,我真的不确定解决这个问题的最佳方法。我知道执行此操作的一种方法是等到最后一个文件被爬网并推送(然后将新属性写入文件),但我不知道如何在异步环境中有效地检测到这一点?我可以经常检查一下,但在我看来这是一种愚蠢的方法。

下面是我导致问题的异步代码。

// Scan directories looking for target file types.
async function scanDirs(){
const
config = await fsp.readFile('./config.json', 'utf8'),
archives = JSON.parse(config).archives,
{ join } = require('path'),
traverse = async (path) => {
try {
const stats = await fsp.stat(path)
if (stats.isDirectory()){
const childPaths = await fsp.readdir(path)
for (const childPath of childPaths){
const
fullPath = join(path, childPath)
traverse(fullPath)
}
} else if (stats.isFile()) {
const
fileTypes = config.fileTypes,
fileExt = path.substring(path.lastIndexOf('.')+1)
if (fileTypes.includes(fileExt)){
const
data = await fsp.readFile('./data.json', 'utf8'),
json = JSON.parse(data),
drive = path.substring(0,1),
files = json[drive].files,
stat = await fsp.stat(path),
newFile = {
"path": path,
"name": path.substring(path.lastIndexOf('\\')+1),
"bytes": stat.size
}
files.push(newFile)
fsp.writeFile('./data.json', JSON.stringify(json, null, 2))
}
}
}
catch (error){
console.error(error)
}
}

for (const path of archives){
traverse(path)
}
}

任何帮助将不胜感激。

最佳答案

I know one way to do this would be to wait until the last file is crawled before writing, but I have no idea how to efficiently detect that in an asynchronous environment?

您将使用Promise.all等待多个 promise :

const { join } = require('path');
async function searchFiles(path, fileTypes) {
try {
const stats = await fsp.stat(path)
if (stats.isDirectory()){
const childPaths = await fsp.readdir(path)
const promises = childPaths.map(childPath =>
searchFiles(join(path, childPath), fileTypes)
);
const results = await Promise.all(promises);
return [].concat(...results);
} else if (stats.isFile()) {
const fileExt = path.substring(path.lastIndexOf('.')+1)
if (fileTypes.includes(fileExt)) {
return [{
"path": path,
"name": path.substring(path.lastIndexOf('\\')+1),
"bytes": stats.size
}];
}
}
} catch(e) {
// ignore. Log?
}
return [];
}
async function readJson(path) {
return JSON.parse(await fsp.readFile(path, 'utf8'));
}

// Scan directories looking for target file types.
async function scanDirs() {
try {
const [config, data] = await Promise.all([readJson('./config.json'), readJson('./data.json')]);
const results = await Promise.all(config.archives.map(path => searchFiles(path, config.fileTypes)));
for (const newFile of [].concat(...results)) {
const drive = newFile.path.substring(0,1);
data[drive].files.push(newFile);
}
fsp.writeFile('./data.json', JSON.stringify(data, null, 2));
} catch (error){
console.error(error)
}
}

顺便说一句,您可能需要考虑使用 path module 中的 basenameextname而不是字符串操作,但考虑到这是一个仅限 Windows 的程序(使用驱动器号),它可能并不重要。

关于javascript - 递归抓取并以异步方式写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58666828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com