Traversing Directory Recursively Nodejs

Viewed 29

I'm traversing a directory recursively but I'm having a hard time keeping track of the previous object and appending its values. I have a log below that shows what's logging.

I think my base case might be incorrect since technically when the function runs it return empty object.

Update

Here is example. When you run this repl I would ignore files that aren't related in the logs.

example if the logs are too noisy (most likely) I would copy the code and run locally with a few directories and files.

Directories / Files

  • ./

    • gamma

      • omega
    • alpha

      • 1.txt
      • 2.txt
      • 3.txt
    • delta

  • help.txt

Code


const fs = require('fs')

function setFlags(){
  console.log('setFlages() not implemented')
}
// recursively read the directory
// getting size and storing objects info
function readDir(path, total = 0, allFiles = {} ){
  // let allFiles = {}
  const files = fs.readdirSync(path)

  //useful information
  if (files.length == 0) {
    return allFiles
  }
  if(files.length > 0) {
    for (let name of files) {
      const stats = fs.statSync(`${path}/${name}`);
      allFiles.name = path
      allFiles.size = stats.size
      allFiles.children = allFiles.children || []
      if (stats.isFile()) {
        // if it's a file than push to the correct child
        allFiles.children.push({ name, size: stats.size })
      } else if (stats.isDirectory()) {
        allFiles.children.push({name, size: total})
        total += stats.size
         readDir(`${path}/${name}`, {...allFiles, children: allFiles.children || []});
      }
  }
  console.log( allFiles)
  }


}

function displayTree(node){

  if (!node) return
  // console.log(node.name, node.size,"bytes")

  if (!node.children)return
  console.group()
  //left child
  for(let child of node.children){
      displayTree(child)
  }
  console.groupEnd()

}



function main(){

  setFlags()
  let tree = readDir('.')
  displayTree(tree)


}
main()

console.log()

logs
{
  name: './alpha',
  size: 0,
  children: [
    { name: '1.txt', size: 0 },
    { name: '2.txt', size: 0 },
    { name: '3.txt', size: 0 }
  ]
}
{
  name: './gamma',
  size: 64,
  children: [ { name: 'omaga', size: [Object] } ]
}
{
  name: './node_modules/fs',
  size: 466,
  children: [
    { name: 'README.md', size: 328 },
    { name: 'package.json', size: 466 }
  ]
}
{
  name: './node_modules',
  size: 128,
  children: [
    { name: '.yarn-integrity', size: 365 },
    { name: 'fs', size: [Object] }
  ]
}
{
  name: '.',
  size: 351,
  children: [
    { name: 'alpha', size: 0 },
    { name: 'delta', size: 160 },
    { name: 'gamma', size: 224 },
    { name: 'help.txt', size: 0 },
    { name: 'index.js', size: 1692 },
    { name: 'node_modules', size: 320 },
    { name: 'package.json', size: 56 },
    { name: 'yarn.lock', size: 351 }
  ]
}

Expected shape of the data

{
    "name": "./",
    "size": 11, 
    "children": [
      {
        "name": "alpha",
        "size": 0,
        "children": [
          {
            name: "1.text",
            size: 0
          }
           {
            name: "2.text",
            size: 0
          }
           {
            name: "3.text",
            size: 0
          }
        ]
      },
      {
        "name": "delta",
        "size": 0,
        "children": []
      }, 
      {
        "name": "gamma",
        "size": 0,
        "children": [
          { 
            name: "omega"
            size: 0
            children: []
          }
        ]
      },
      {
          name: "help.txt",
          size: 11
      }
    ] 
  }
1 Answers
const fs = require('fs')

// recursively read the directory
// getting size and storing objects info
function readTree(path ){
  let parent = {}
  parent.name = path
  parent.size = 0
  parent.children = []
  const names = fs.readdirSync(path)


  for (let name of names) {
    const stats = fs.statSync(${path}/${name});
    if (stats.isFile()) {
      // if it's a file than push to the correct child
      parent.children.push({ name, size: stats.size })
      //add child size to parent size
      parent.size += stats.size
    } else if (stats.isDirectory()) {
      let dirObj = readTree(${path}/${name}, {...parent});
      // if it's a file than push to the correct child
      dirObj.name = name + '/'
      parent.children.push(dirObj)
      //add child size to parent size
      parent.size += dirObj.size

    }
  }
  return parent
} 
Related