Wie schnell ist fs.readdirSync? Kann ich es beschleunigen?
P粉064448449
P粉064448449 2023-09-04 19:48:56
0
1
626
<p>Ich habe eine Funktion, die mithilfe von fs.readdirSync rekursiv alle Dateien in einem Verzeichnis abruft. Mit dem kleinen Verzeichnis hat es gut funktioniert. Ich habe es als Test ausgeführt, aber jetzt führe ich es in einem Verzeichnis aus, das über 100 GB groß ist, und es dauert lange, bis es fertig ist. Irgendwelche Ideen, wie man das beschleunigen kann oder ob es einen besseren Weg gibt? Irgendwann muss ich das bei einigen Verzeichnissen ausführen, die Terabytes an Daten enthalten. </p> <pre class="brush:php;toolbar:false;">// Rekursive Funktion zum Abrufen von Dateien Funktion getFiles(dir, files = []) { // Mit fs.readdirSync ein Array aller Dateien und Verzeichnisse im übergebenen Verzeichnis abrufen const fileList = fs.readdirSync(dir); // Erstelle den vollständigen Pfad der Datei/des Verzeichnisses, indem du das übergebene Verzeichnis und den Datei-/Verzeichnisnamen verkettest for (const-Datei von fileList) { const name = `${dir}/${file}`; // Überprüfen Sie mithilfe von fs.statSync, ob die aktuelle Datei/das aktuelle Verzeichnis ein Verzeichnis ist if (fs.statSync(name).isDirectory()) { // Wenn es sich um ein Verzeichnis handelt, rufen Sie rekursiv die Funktion getFiles mit dem Verzeichnispfad und dem Dateiarray auf getFiles(name, files); } anders { // Wenn es sich um eine Datei handelt, den vollständigen Pfad zum Dateiarray übertragen files.push(name); } } Rückgabedateien; }</pre></p>
P粉064448449
P粉064448449

Antworte allen(1)
P粉696146205

不幸的是,异步速度较慢。所以我们需要优化你的代码。您可以使用 {withFileTypes:true} 选项来完成此操作,速度提高 2 倍。

我还尝试过节点 v20 的 {recursive:true} 选项,但它甚至比您的解决方案还要慢。它不适用于 withFileTypes

也许具有高读取速度的更好 SSD 会有所帮助。虽然我猜文件条目是从文件系统索引读取的,但不确定硬件如何影响它。

import fs from 'fs';

const DIR = '/bytex';

function getFiles(dir, files = []) {
    // Get an array of all files and directories in the passed directory using fs.readdirSync
    const fileList = fs.readdirSync(dir);
    // Create the full path of the file/directory by concatenating the passed directory and file/directory name
    for (const file of fileList) {
        const name = `${dir}/${file}`;
        // Check if the current file/directory is a directory using fs.statSync
        if (fs.statSync(name).isDirectory()) {
            // If it is a directory, recursively call the getFiles function with the directory path and the files array
            getFiles(name, files);
        } else {
            // If it is a file, push the full path to the files array
            files.push(name);
        }
    }
    return files;
}

function getFiles2(dir, files = []) {
    const fileList = fs.readdirSync(dir, { withFileTypes: true });
    fileList.forEach(file => file.isDirectory() ? getFiles2(`${dir}/${file.name}`, files) : files.push(`${dir}/${file.name}`));
    return files;
}

let start = performance.now();
let files = getFiles(DIR);
console.log(performance.now() - start);
console.log(files.length);

start = performance.now();
files = getFiles2(DIR);
console.log(performance.now() - start);
console.log(files.length);

输出:

171.66947209835052
64508
68.24071204662323
64508
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage