Jim Lawless' Blog


Directory Traversal in Rhino JavaScript

Originally published on: Tue, 6 Jul 2010

I needed to perform several operations on some files in a large subdirectory tree. I decided to use Rhino JavaScript as the source language.

I wrote a function called spanDir() that accepts two parameters:

  1. A string representing the root directory path that the function is meant to scan.
  2. A closure that accepts a parameter of type java.io.File.

spanDir() first obtains a list of all files in the specified directory in the form of an array of java.io.File objects. Then, spanDir() iterates over the array. As it encounters a File object which is also an array, it recursively calls itself before invoking the closure.

Please refer to the function below.

spanDir.js

   // spanDir - a directory traversal function for
   // Rhino JavaScript
   // Copyright 2010 by James K. Lawless
   // See MIT/X11 license at 
   // http://www.mailsend-online.com/wp/license.php

importPackage(java.io);

      // spanDir() accepts two parameters
      // The first is a string representing a directory path
      // The second is a closure that accepts a parameter of type
      // java.io.File
   function spanDir(dir,dirHandler) {
      var lst=new File(dir).listFiles();
      var i;
      for(i=0;i<lst.length;i++) {
            // If it's a directory, recursive call spanDir()
            // so that we end up doing a scan of
            // the directory tree
         if(lst[i].isDirectory()) {
            spanDir(lst[i].getAbsolutePath(),dirHandler);
         }
            // Pass the File object to the handler that
            // the caller has specified regardless of whether
            // the File object is a directory.
         dirHandler(lst[i]);
      }
   }


In order to use this new function, we need a callback function that can process a File object. In the script below, I have created a small function called showIt() that serves this purpose. dir.js

   // Copyright 2010 by James K. Lawless
   // See MIT/X11 license at 
   // http://www.mailsend-online.com/wp/license.php

load("spanDir.js");

      // A simple worker-bee function that will print the absolute path
      // name of the File object passed to it.
   function showIt(fil) {
      print(fil.getAbsolutePath());
   }

      // Invoke the recursive spanDir() engine on the current
      // directory, ".", using the showIt() function as the
      // closure that we pass in.
   spanDir(".\\",showIt);

You can execute the above script by using the following command-line:
   java -jar js.jar dir.js

You should see listed on the console the names of all files and directories beginning at the current directory including all subdirectories.

Alternately, we can use an anonymous function in place of showIt() for brevity.

dir2.js

   // Copyright 2010 by James K. Lawless
   // See MIT/X11 license at 
   // http://www.mailsend-online.com/wp/license.php

load("spanDir.js");

      // This script is an alternate version of dir.js 
      // We'll use an anonymous function as a closure.

      // Invoke the recursive spanDir() engine on the current
      // directory, "."/
   spanDir(".\\",
      function(fil) {
         print(fil.getAbsolutePath());
      }
   );

Using the spanDir() function, I can now simplify processing files in a directory tree. Let's say that I only wanted to list files that are not directories whose names end in ".xml" ( in either upper-case or lower-case text.)

The following script performs this task.

dirxml.js

   // Copyright 2010 by James K. Lawless
   // See MIT/X11 license at 
   // http://www.mailsend-online.com/wp/license.php

load("spanDir.js");

      // Print the filename only if the File object is an
      // XML file.
   function showXML(fil) {
      var nam;
      nam=fil.getAbsolutePath();
      if(!fil.isDirectory()) {
         if(nam.toLowerCase().endsWith(".xml")) {
            print(nam); 
         }
      }
   }

   spanDir(".\\",showXML);

I can now focus on what I want to do once I find a particular type of file and can let the spanDir() engine handle the task of calling the function for every file in the specified directory.

The source code for the above scripts can be found here:

http://www.mailsend-online.com/wp/spandir.zip

Unless otherwise noted, all code and text entries are Copyright ©2010 by James K. Lawless



Views expressed in this blog are those of the author and do not necessary reflect those of the author's employer. Views expressed in the comments are those of the responding individual.

stumbleupon Save to StumbleUpon
digg Digg it
reddit Save to Reddit
facebook Share on Facebook
twitter Share on Twitter
aolfav More bookmarks


Previous post: Taking Shape
Next post:Compiling Rhino JavaScript to Java


About Jim ...


Click **here**
to try out MailWrench;
a command-line SMTP /
SMTPS (Google Gmail)
mailer for Windows.


Follow me on Twitter

http://twitter.com/lawlessGuy


Recent Posts

A JavaScript REPL for Android Devices

MailSend is Free

My Blog Engine

The October 10th Bug

A Review of Kevin Mitnick's Book Ghost in the Wires

Spellbound by Web Programming

Backlinks to my Blog Posts

Play MP3 Files with Python on Windows


Random Posts

Spellbound by Web Programming

Choose your own Adventure with Sinatra

Yet Another Enhanced Echo Command

Invoking the Default Windows Screen-Saver

Thwarting HTTP Referer Trackbacks

Setting Windows Console Text Colors in C

Book Review : Using Google App Engine

Shrouding CSharp and Java Source Code with AWK

Auto Save Clipboard Images Redux

Structuring my Thinking


Full List of Posts

http://www.mailsend-online.com/bloglist.htm


Recent Posts from my Other Blog

Remembering Dr. San Guinary

Why Some Web Sites will go Dark on Jan 18th

SNL Superhero Skit

More Ruby Games

My Ruby Game Challenge Entry

Steal this Bookmarklet

Nerd Toys

Learn New Jargon, You Must

Spot the Wiebe

Tech Magazine Glory Days

Book Review : Paull Allen - Idea Man

A 90's Experiment in Online Systems - The U.S. West CommunityLink Service