-1

I'm trying to make a file indexer by node.js. The program is supposed to index files and folders in an array and also check inside folders and add all sub folders and files

I wrote:

fs.readdir(__dirname,index);

function index(err,data){
 for (i in data){
        if(fs.statSync(data[i]).isDirectory()){
            j.folders.push(path.resolve(data[i]));
            fs.readdir(data[i],index);
        }
        else{
            j.files.push(path.resolve(data[i]));
        }
    } 
} 

... this code, but when it passes inside a folder it gives traceback and stops executing. here my question is how I index files and solve this issue.

ps. please don't comment about walk, I want to write my own module.

closed as unclear what you're asking by Ixrec, durron597, Robert Harvey, user22815, user40980 May 10 '15 at 0:24

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    What is your question? If you're asking for code troubleshooting help, you're in the wrong place. – Robert Harvey May 10 '15 at 0:01
  • Contrary to popular belief, the contents of a call stack trace contains information you can use to determine things about the problem. – Lars Viklund May 10 '15 at 1:54
-2

An issue with readdir is that it passes in only the filename, without the full path, to the data variable in your index function. Let's say you are calling the script from C:\main. The contents of C:\main are

C:\main C:\main\folder1 C:\main\folder1\subDir1

Once your program enters folder1 and reads subDir1, it will try to call readdir with data[i] = 'subDir1'. But since the current working directory hasn't changed, which is still C:\main, readdir joins this to its path argument, resulting in C:\main\subDir1, which doesn't exist.

To handle this, we can track the directory that was sent in to readdir, which is asynchronous. This means that the directory needs to be defined in the callback function before it is invoked.

var fs = require('fs');
var path = require('path');
var files = [];
var folders = [];

indexDir(__dirname);


function indexDir(d) {fs.readdir(d, function (err,data){
 for (i in data){
        console.log(path.join(d, data[i]));
        if(fs.statSync(path.join(d, data[i])).isDirectory()){
            folders.push(path.resolve(path.join(d, data[i])));
            indexDir(path.join(d, data[i]));
        }
        else{
            files.push(path.resolve(path.join(d, data[i])));
        }
    }
})}

If we want to see the results once the directory has been completely traversed, then it might be easier to just use readdirSync, since it is synchronous and will block until all the directories have been visited. Otherwise, if we want to keep things asynchronous, we can call another function when everything is done by keeping track of the number of asynchronous calls.

var fs = require('fs');
var path = require('path');
var files = [];
var folders = [];
var calls = 0;
indexDir(__dirname);

function indexDir(d) {
 calls++;
 fs.readdir(d, function (err,data){
   calls--;
   for (i in data){
          if(fs.statSync(path.join(d, data[i])).isDirectory()){
              folders.push(path.resolve(path.join(d, data[i])));
              indexDir(path.join(d, data[i]));
          }
          else{
              files.push(path.resolve(path.join(d, data[i])));
          }
      }
   if (calls == 0){
     present();
   }
 })}


function present(){
 for (i in files){
        console.log(files[i]);
    }
 for (i in folders){
        console.log(folders[i]);
    }
 }
  • @strechray thank you it works perfect but because it is async i cannot reach it from another page it gives empty array unles i change it to readdirSync is there a way to import a module when it is ready? – nikoss May 10 '15 at 17:33
  • @nikoss you can nest another function call when all the readdirs are complete. You may use something like Q promises, or else just keep track of the number of calls yourself with a counter to know when it is done. I will edit the answer to include some example code. – stechray May 10 '15 at 20:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.