Convert a Directory Structure in the Filesystem to JSON with Node.Js

Node.js convert directory tree to JSON

You could create a function to convert a directory to an object, with a property for each dir / file.

This would then be called recursively to walk the entire tree, in this case using the fs/promises functions.

const fs = require('fs/promises'); 
const path = require('path');

async function walkDir(dir, result = {}) {
let list = await fs.readdir(dir);
for(let item of list) {
const itemPath = path.join(dir, item);
let stats = await fs.stat(itemPath)
if (await stats.isDirectory()) {
result[item] = {};
await walkDir(itemPath, result[item]);
} else {
const fileName = path.basename(item, path.extname(item));
result[fileName] = JSON.parse(await fs.readFile(itemPath, { encoding: 'utf-8'}));
}
}
return result;
}

async function testWalkDir() {
let result = await walkDir('./CMS')
console.log("Result:", JSON.stringify(result, null, 2));
}

testWalkDir();

Assuming each file looks like

{
"some_key": "some_val"
}

I get a result that looks like so:

{
"en": {
"brand_one": {
"footer": {
"some_key": "some_val"
},
"header": {
"some_key": "some_val"
}
},
"brand_three": {
"footer": {
"some_key": "some_val"
},
"header": {
"some_key": "some_val"
}
},
"brand_two": {
"footer": {
"some_key": "some_val"
},
"header": {
"some_key": "some_val"
}
}
}
}

Convert a directory structure in the filesystem to JSON with Node.js

Here's a sketch. Error handling is left as an exercise for the reader.

var fs = require('fs'),
path = require('path')

function dirTree(filename) {
var stats = fs.lstatSync(filename),
info = {
path: filename,
name: path.basename(filename)
};

if (stats.isDirectory()) {
info.type = "folder";
info.children = fs.readdirSync(filename).map(function(child) {
return dirTree(filename + '/' + child);
});
} else {
// Assuming it's a file. In real life it could be a symlink or
// something else!
info.type = "file";
}

return info;
}

if (module.parent == undefined) {
// node dirTree.js ~/foo/bar
var util = require('util');
console.log(util.inspect(dirTree(process.argv[2]), false, null));
}

Convert directory structure in the filesystem to Json object

Finally I figured out the solution, here it is if anybody needs it:

var diretoryTreeToObj = function (dir, done) {
var results = {};
var _contents = [];
var files = [];
fs.readdir(dir, function (err, list) {
if (err) {
return done(err);
}
var pending = list.length;
if (!pending) {
return done(null, {name: path.basename(dir), type: 'folder', children: results});
}
list.forEach(function (file, index) {
file = path.resolve(dir, file);
fs.stat(file, function (err, stat) {
results['_contents'] = files;
if (stat && stat.isDirectory()) {
diretoryTreeToObj(file, function (err, res) {
results[path.basename(file)] = res;
if (!--pending) {
done(null, results);
}
});
} else {
files.push({
name: path.basename(file),
path: file
});
results['_contents'] = files;
if (!--pending) {
done(null, results);
}
}
});
});
});
};

Folder structure to json

Interesting problem. Here's my solution, using sync functions. The output JSON will contain an array of objects that can be either strings (for file names) or objects (for directories).

Code (live):

var fs = require('fs'), path = require('path'), util = require('util');

var dirToJSON = function(dir, done) {
var results = [];

function recWalk(d, res) {
var list = fs.readdirSync(d);
list.forEach((name) => {
var tempResults = [];
var file = path.resolve(d, name);
var stat = fs.statSync(file);
if (stat && stat.isDirectory()) {
recWalk(file, tempResults);
var obj = {};
obj[name] = tempResults;
res.push(obj);
} else {
res.push(name);
}
});
}

try {
recWalk(dir, results);
done(null, results);
} catch(err) {
done(err);
}
};

dirToJSON("/home/", function(err, results) {
if (err) console.log(err);
else console.log(util.inspect(results, {showHidden: false, depth: null}));
});

Output:

[ { node: [ '.bash_logout', '.bashrc', '.profile' ] },
{ runner:
[ '.bash_logout',
'.bashrc',
'.profile',
'config.json',
'index.js',
{ node_modules: [] },
'test.js' ] } ]

Note that I'm printing results with util.inspect to allow infinite depth for objects, but you can also do JSON.stringify(results)

How to covert json into tree like folder structure in javascript

You could use the following code. It first creates a nested structure where the folder names are also keys in the parent object. A node may be created even before the modified date is encountered in the source structure. reduce is used to walk through the folders of a single path, deepening the object structure.

This creates a structure like this:

{
"folders": {
"index": {
"path": "index",
"modified": "2018-09-05T14:33:25.520-04:00",
"folders": {
"library": {
"path": "library",
"modified": "2018-09-05T14:33:29.763-04:00",
"folders": {
"abc": {
"path": "abc",
"modified": "2018-09-05T14:33:29.816-04:00"
},
"abc_form": {
"path": "abc_form",
"modified": "2018-09-05T14:33:29.841-04:00",
"folders": {
"abc_thankyou": {
"path": "abc_thankyou",
"modified": "2018-09-05T14:33:29.867-04:00"
},
"abc_thankyou_d": {
"path": "abc_thankyou_d",
"modified": "2018-09-05T14:33:29.892-04:00"
}
}
},
"index": {
"path": "index",
"modified": "2018-09-05T14:33:29.788-04:00"
}
}
},
"contact": {
"path": "contact",
"modified": "2018-09-05T14:33:29.511-04:00",
"folders": {
"contact-thankyou": {
"path": "contact-thankyou",
"modified": "2018-09-05T14:33:29.565-04:00"
}
}
},
"downloads": {
"path": "downloads",
"modified": "2018-09-05T14:33:29.376-04:00",
"folders": {
"downloads-thank-you": {
"path": "downloads-thank-you",
"modified": "2018-09-05T14:33:29.402-04:00"
},
"downloads-thank-you-abc": {
"path": "downloads-thank-you-abc",
"modified": "2018-09-05T14:33:29.427-04:00"
}
}
}
}
}
}
}

Depending on your needs, you may want to replace the object folders with an array.

Note that your input has two versions of the modified date: Lastmodifed and modifed -- both with the spelling mistake. I have assumed that your data is just like that:

function toTree(files) {    const root = {};    // Create structure where folder name is also a key in parent object    for (const {Path, Lastmodifed, modifed} of files) {        Path.match(/[^\/]+/g).reduce((acc, folder) => {            if (!acc.folders) acc.folders = {};            return acc.folders[folder] || (acc.folders[folder] = { path: folder, modified: null });         }, root).modified = Lastmodifed || modifed;    }    // Optional: replace folders object by folders array, recursively    (function recurse(node) {        if (!node.folders) return;        node.folders = Object.values(node.folders);        node.folders.forEach(recurse);    })(root);    return root;}
const files = [{"modifed": "2018-09-05T14:33:29.816-04:00","Path": "/index/library/abc"},{"modifed": "2018-09-05T14:33:29.867-04:00","Path": "/index/library/abc_form/abc_thankyou"},{"modifed": "2018-09-05T14:33:29.892-04:00","Path": "/index/library/abc_form/abc_thankyou_d"},{"modifed": "2018-09-05T14:33:29.841-04:00","Path": "/index/library/abc_form"},{"modifed": "2018-09-05T14:33:29.788-04:00","Path": "/index/library/index"},{"modifed": "2018-09-05T14:33:29.763-04:00","Path": "/index/library"},{"modifed": "2018-09-05T14:33:29.565-04:00","Path": "/index/contact/contact-thankyou"},{"modifed": "2018-09-05T14:33:29.511-04:00","Path": "/index/contact"},{"Lastmodifed": "2018-09-05T14:33:29.402-04:00","Path": "/index/downloads/downloads-thank-you"},{"Lastmodifed": "2018-09-05T14:33:29.427-04:00","Path": "/index/downloads/downloads-thank-you-abc"},{"Lastmodifed": "2018-09-05T14:33:29.376-04:00","Path": "/index/downloads"},{"Lastmodifed": "2018-09-05T14:33:25.520-04:00","Path": "/index"}];console.log(toTree(files));

Create JSON based on file structure in ruby, python, or node.js script

The question is rather ill-defined, but here is my best shot at interpreting what you want. Extending this to adding file-paths and more groups of items is left as an exercise to the reader.

from re import split
from itertools import groupby, izip

fruits = set(["apple", "pear"])
animals = set(["bear", "cat"])

json_structure = {}

text_input = ["apple001.png", "apple002.jpg", "bear001.png", "pear001.png", "cat001.png"]

def check(filename):
"""Checks which group a filename is in and returns an integer for ordering"""
n = split(r'[0-9]', filename)[0]
if n in fruits:
return 0
else:
return 1

grouped = groupby(sorted(text_input, key=check), key=check)

for objects, object_type in izip(grouped, ["fruits", "animals"]):
items = objects[1]
json_structure[object_type] = list(items)

print json_structure

Calculate Directory from file full path in JSON directory tree

You could set path by taking name property and iterate children, if exist and hand over the last path.

function setPath(object, path = '') {    (object.children || []).forEach(o => {        var temp = setPath(o);        if (temp) object.path = temp.slice(0, temp.lastIndexOf('/'));    });    return object.path;}
var data = { path: null, size: 600, type: "directory", children: [{ path: null, size: 400, type: "directory", children: [{ path: null, size: 400, type: "directory", children: [{ path: "photos/summer/june/windsurf.jpg", name: "windsurf.jpg", size: 400, type: "file", extension: ".jpg" }] }] }, { path: null, size: 200, type: "directory", children: [{ path: null, size: 200, type: "directory", children: [{ path: "photos/winter/january/ski.png", name: "ski.png", size: 100, type: "file", extension: ".png" }, { path: "photos/winter/january/snowboard.jpg", name: "snowboard.jpg", size: 100, type: "file", extension: ".jpg" }] }] }] };
setPath(data);
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

transform file/directory structure into 'tree' in javascript

You can do it like this:

var arr = [] //your array;
var tree = {};

function addnode(obj){
var splitpath = obj.path.replace(/^\/|\/$/g, "").split('/');
var ptr = tree;
for (i=0;i<splitpath.length;i++)
{
node = { name: splitpath[i],
type: 'directory'};
if(i == splitpath.length-1)
{node.size = obj.size;node.type = obj.type;}
ptr[splitpath[i]] = ptr[splitpath[i]]||node;
ptr[splitpath[i]].children=ptr[splitpath[i]].children||{};
ptr=ptr[splitpath[i]].children;
}
}

arr.map(addnode);
console.log(require('util').inspect(tree, {depth:null}));

Output

{ storage:
{ name: 'storage',
type: 'directory',
children:
{ test:
{ name: 'test',
type: 'directory',
size: 0,
children:
{ asdf:
{ name: 'asdf',
type: 'directory',
size: 170,
children: { '2.txt': { name: '2.txt', type: 'file', size: 0, children: {} } } } } } } } }


Related Topics



Leave a reply



Submit