如何正确地递归遍历磁盘目录,并使用node.js以相对格式将所有路径流式传输到json中?

时间:2019-03-04 10:19:08

标签: javascript node.js

我正在尝试使用具有以下逻辑的node.js读取目录树并将其保存到JSON文件中:

  1. 读取指定目录
  2. 将路径转换为relative格式(如果可能的话,放在第一位吗?)。像这样:

目录: C:/test

{
{"C:/test folder 1": [
  {"folder 1": ["file1.txt", "file2.txt"]}, 
  "file1.txt",
  "file2.txt",
  ...
]},
{"C:/test folder 2": [
  {"folder 1": ["file1.txt", "file2.txt"]}, 
  "file1.txt",
  "file2.txt",
  ...
]},
"file1.txt",
"file2.txt",
"file3.txt",
...
}
  1. 将该对象流式传输到JSON文件中(我需要对其进行流式传输,因为对象很大)

我试图使用不同的npm模块,例如:

walkdirwalkernode-klaw + fs-extra.writeJsonjson-object-stream

但是尝试将其流式传输到json时,我一直遇到不同的错误。

1 个答案:

答案 0 :(得分:2)

以下脚本将为您工作,只需将__dirname替换为要列出的绝对位置路径即可。并更新文件名写入位置

我不是在这里检查第一次调用是否真的得到了有效的文件夹,并且在OS上可能存在与/有关的问题

removeNamespace标志只是为了使第一级保持绝对路径,而不是紧随其后

var fs = require("fs");

function getContentForLocation(location, removeNamespace) {
    let result = [];
    let content = fs.readdirSync(location);
    content.forEach(c => {
        if(fs.statSync(`${location}/${c}`).isFile()) result.push(c);
        else {
            let name = removeNamespace ? c : `${location}/${c}`;
            result.push({
                [`${name}`]: getContentForLocation(`${location}/${c}`, true)
            })
        }
    });
    return result;
}
let tree = JSON.stringify(getContentForLocation(__dirname))
fs.writeFileSync(`${__dirname}/test.json`, tree)

异步版本:

var fs = require("fs");

function getContentForLocation(location, callback, removeNamespace) {
    let result = [];

    let folderNames = [];
    fs.readdir(location, (err, content) => {
        content.forEach(c => {
            if(fs.statSync(`${location}/${c}`).isFile()) result.push(c);
            else folderNames.push(c);
        });
        if(folderNames.length === 0) callback(result)
        else folderNames.forEach(folder => {
            let name = removeNamespace ? folder : `${location}/${folder}`;
            getContentForLocation(`${location}/${folder}`, resolveCallback.bind(this, name, folder),true)
        })
    });

    function resolveCallback(name, folder, content) {
        result.push({ [name]: content });
        folderNames = folderNames.filter(f => f !== folder);
        if(folderNames.length === 0) callback(result);
    }
}

getContentForLocation(__dirname, results => {
    console.log("resolved", results)
    fs.writeFile(`${__dirname}/test.json`, JSON.stringify(results), (err) => { console.log(err) })
});