Folders

Folder Basics

Important Folder Locations

Jaxer.System provides several convenient properties for locating important system folders in a cross platform manner.

  • User folders: The Desktop folder of the user account running Jaxer is located with the Jaxer.System.desktopFolder, and the home folder is located with Jaxer.System.homeFolder.
  • Jaxer Binaries: The Folder containing the Jaxer binaries is located with the Jaxer.System.executableFolder
  • Jaxer Temporary Folder: The Jaxer temporary folder is located with the Jaxer.System.tempFolder
var desktopFolder = Jaxer.System.desktopFolder;  
var homeFolder = Jaxer.System.homeFolder;
var executableFolder = Jaxer.System.executableFolder;
var tempFolder = Jaxer.System.tempFolder;

Simple Folder vs. Folder Objects

Whether you create an object or use the static methods, Jaxer creates a Folder object, so the key reason to use a Folder object boils down to convenience. If you'll only be calling one or two methods against the folder then static is simpler; for more complex work create an object and store it in a variable for reuse.

Operating Systems and Paths

Working with Filepaths

Jaxer can handle filesystem paths as well as file:/// urls and provides convenience methods to resolve provided paths to an actual location on the filesystem.

Converting between a filesystem path and a URL

var fileUrl = Jaxer.Dir.pathToUrl("c:\\aptana")   
// fileUrl -> file:///c:/aptana/  
var filePath = Jaxer.Dir.urlToPath("file:///c:/aptana");  
//  filePath -> c:\aptana

Resolve a relative file path into an absolute path

var indexPath = Jaxer.Dir.resolve("index.html")   
// indexPath  -> C:\aptana\source\public\fileGrep\index.html  
var folderPath = Jaxer.Dir.resolve(".")   
// folderPath -> C:\aptana\source\public\fileGrep  
var parentPath = Jaxer.Dir.resolve("..")   
// parentPath -> C:\aptana\source\public  
var grandParentPath = Jaxer.Dir.resolve("../..")   
// grandParentPath -> C:\aptana\source

Using a combination of these methods will generally allow you to manipulate a provided path or Url to the required path.

Cross Platform Filepaths

Linux, Mac OS X and other *NIX operating systems require a forward slash to separate folder names when specifying the path for a file while MS Windows uses a back slash.

Further complicating things is that to include a backslash in a string in JavaScript you work around the fact that JavaScript uses backslash as a signal to escape the following character(s) and treat them as literals rather than commands—\n would normally be treated as the new line character. To escape a backslash you must use two ('\\').

One method Jaxer provides to deal easily with these issues, a good choice for when you need to build a string to keep for use later, is Jaxer.System.separator. It returns the system path separator, as a string.

var folderUrl = Jaxer.Dir.pathToUrl("c:" + Jaxer.System.separator + "aptana");
// folderUrl  -> file:///c:/aptana/

A cleaner way to do this is with Jaxer.Dir.combine(args) method, which concatenates a list of parts into a full path joined with the platform path separator and cleans any extra path separators contained in the list.

var newPath = Jaxer.Dir.combine(Jaxer.System.tempFolder,'afolder','afile.txt');
// on windows -> C:\aptana\JaxerDev\tmp\afolder\afile.txt
// on linux -> /opt/aptana/jaxer/afolder/afile.txt

Simple Folder Access

Checking whether a Folder Exists

Use Jaxer.Dir.exists(), which returns true if the path exists on the filesystem and false if not.

Jaxer.Dir.exists(Jaxer.System.tempFolder);
// returns true as tempFolder resolves to a real part of the filesystem

Finding Filenames which Match a Pattern

Use Jaxer.Dir.grep() to get a list of file objects that match a specified pattern:

var myResults = Jaxer.Dir.grep(Jaxer.Dir.resolve(''),{pattern:'^.*html$'});

This example returns an array of all the html files contained in the current folder. Navigating the filesystem has a more in depth review of this functionality.

Using Folder Objects

Instantiating

Create a folder object by newing up Jaxer.Dir(pathToFile). However, creating a folder object does not automatically create the equivalent folder on the file system. To make the folder real, you may either call create() on a dir object you previously instantiated or use the static version of create(), passing the resolved pathToFile as a parameter. Both create() methods take a permissions string (e.g., 0644, 0777). The static version returns a Folder object.

Jaxer.Dir expects to be created with resolved paths, which means the parameter must be a full path to the file system object. As a contra-example, the following code throws a NS_ERROR_FILE_UNRECOGNIZED_PATH error.

var myFolder = Jaxer.Dir('newfolder');

To avoid this issue, use Jaxer.Dir.resolve(path) when creating the folder parameter.

var folderPath = Jaxer.Dir.resolve('newfolder');
// Make a Jaxer.Dir object first
var myFolder = new Jaxer.Dir(folderPath);
myFolder.create('0644');
// OR use the static version
var myFolder = Jaxer.Dir.create(folderPath, '0644');

Getting Information

A folder object has a lot of useful information that you can get using its accessor methods.

The most commonly used method for folder objects is exists(). This provides us with a boolean value predicated on the existence of the referenced folder on the file system.

// if the folder doesn't exist create an empty folder.  
if (!myFolder.exists())  
{  
    myFolder.create();        
}

Now that we have an instantiated folder object called 'myFolder' that we know exists, we can interrogate it to get useful information about the folder and its properties:

var path = myFolder.path; // C:\aptana\JaxerDev\public\work\new  
var parentPath = myFolder.parentPath; // C:\aptana\JaxerDev\public\work  
var dateModified = myFolder.dateModified; 
	// Wed Mar 05 2008 14:52:03 GMT-0800 (Pacific Standard Time)  
  
var isDir = myFolder.isDir(); // true  
var isFile = myFolder.isFile(); // false  
var isExec = myFolder.isExec(); // false  
var isSymlink = myFolder.isSymlink(); // false  
var isWritable = myFolder.isWritable(); // true  
var isReadable = myFolder.isReadable(); // true  
var isHidden = myFolder.isHidden(); // false  
var isSpecial = myFolder.isSpecial(); // false

Creating a Folder

Invoke the create() method on a dir object.

var myFolder = new Jaxer.Dir(Jaxer.Dir.resolve('myFolder.txt'));  
if (!myFolder.exists())   
{  
    myFolder.create();  
}

Deleting a Folder

Use the remove() method:

// if the folder exists delete it   
if (myFolder.exists())  
{  
    myFolder.remove();        
}

Jaxer includes methods for easily retrieving the contents of folders. However, programmatically navigating the filesystem can result in a lot of scaffolding code so Jaxer also provides grep and map methods for more powerful scans and operations against the filesystem.

Sample Folder and File Layout
c:\rootFolder\
----foo.txt
----bar.txt
----subFolder1\
--------foo1.txt
--------foo2.txt
--------foo3.html (1)
--------ignore.html
----subFolder2\
--------a.js
--------b.js
--------c.js
----subFolder3\
-------subFolder3a\
------------deepFOO1.txt (2)
------------deepFOO2.txt
Example Paths
(1) c:\rootFolder\subFolder1\foo3.html
(2) c:\rootFolder\subFolder3\subFolder3a\deepFOO1.txt

Searching for Files and Folders (Jaxer.Dir's readDir())

Read and process entries in a directory.
var rootDir = new Jaxer.Dir('c:\\rootFolder');  
var folderEntries = rootDir.readDir();  
  
for (var index = 0; index < folderEntries.length; index++)   
{  
    var fileSystemObject = folderEntries[index];     
      
    if (fileSystemObject.isFile)   
    {  
        // process the file  
    }  
    if (fileSystemObject.isDir)   
    {  
       // process the file  
    }  
} 

Finding Folders which Match a Pattern (Jaxer.Dir.grep)

Jaxer.Dir.grep takes two parameters, path and options:

  • Path: directory path to the folder to search.
  • Options: Javascript Object that contains properties to fine tune the search, including pattern, flags and recursive. 
 Pattern is a string containing a JavaScript regular expression, 
flags contains regexp flags to govern the behavior of the pattern parameter and 
recursive indicates whether the search should scan sub-folders.

Simple Grep

var rootFolder = new Jaxer.Dir("c:\\rootFolder");  
var myResults = Jaxer.Dir.grep(rootFolder);
Simple Grep Results
c:\rootFolder\bar.txt
c:\rootFolder\foo.txt

Match a single file in the top-level folder

var myResults = Jaxer.Dir.grep(rootFolder,{pattern:'^.*foo.*$'}); // c:\rootFolder\foo.txt

Recursive Search

var myResults = Jaxer.Dir.grep(rootFolder,{pattern:'^.*foo.*$',recursive:true});
// returns array containing:
c:\rootFolder\foo.txt
c:\rootFolder\subFolder1\foo1.txt,
c:\rootFolder\subFolder1\foo2.txt
c:\rootFolder\subFolder1\foo3.html

Make Search Case-Insensitive

var myResults = Jaxer.Dir.grep(rootFolder,{pattern:'^.*foo.*$',flags:'i',recursive:true});
// returns array of:
c:\rootFolder\foo.txt,
c:\rootFolder\subFolder1\foo1.txt
c:\rootFolder\subFolder1\foo2.txt
c:\rootFolder\subFolder1\foo3.html
c:\rootFolder\subFolder3\subFolder3a\deepFOO1.txt
c:\rootFolder\subFolder3\subFolder3a\deepFOO2.txt

Object literal Options Parameter

var opt = {pattern:'^.*[12]\..*$',recursive:true};  
var myResults = Jaxer.Dir.grep("c:\\rootFolder",opt); 
// returns array of:
c:\rootFolder\subFolder1\foo1.txt
c:\rootFolder\subFolder1\foo2.txt
c:\rootFolder\subFolder3\subFolder3a\deepFOO1.txt
c:\rootFolder\subFolder3\subFolder3a\deepFOO2.txt

Operating on Folders which Match a Pattern (Jaxer.Dir.map)

Jaxer.Dir.map adds an optional third parameter to Grep's two, a function to invoke on each matched file object. The function can be inline/anonymous, named reference or left off, in which case the behavior is identical to Grep. The function gets a single parameter, the File object to operate on.

Since some searches can take a bit of time, depending on the depth of the nesting or complexity of the callback function, take care not to cause a timeout.

Write File Info to a Log

var myResults = Jaxer.Dir.map(  
    rootFolder,  
    {pattern:'^.*[12]\..*$',recursive:true },  
    function(f) { Jaxer.Log.info(f.getPath()); return f }));  
// writes a log entry for each matched file AND 
//	returns the array of Jaxer.File objects:
13:55:19 02/20/2008 [  2356] [INFO] [JS Framework] [framework.] c:\rootFolder\subFolder1\foo1.txt
13:55:19 02/20/2008 [  2356] [INFO] [JS Framework] [framework.] c:\rootFolder\subFolder1\foo2.txt
13:55:19 02/20/2008 [  2356] [INFO] [JS Framework] [framework.] c:\rootFolder\subFolder3\subFolder3a\deepFOO1.txt
13:55:19 02/20/2008 [  2356] [INFO] [JS Framework] [framework.] c:\rootFolder\subFolder3\subFolder3a\deepFOO2.txt

Same Code using a Named Callback

function logMatch(f)   
{  
    Jaxer.Log.info(f.getPath());   
    return f  
};  
var opt = {  
    pattern:'^.*[12]\..*$',  
    recursive:true  
};  
var myResults = Jaxer.Dir.map(rootFolder,opt,logMatch)); 

Using a Decorator Function to Format the Results

function fileDecorator(f)  
{  
    var decoratorOutput = [];  
      
    decoratorOutput.push(f.getLeaf());  
    decoratorOutput.push(f.getSize());  
    decoratorOutput.push(f.getExt());  
    decoratorOutput.push(f.getDateModified());  
    decoratorOutput.push(f.getParentPath());  
      
    return decoratorOutput.join("|") ;  
}  
var fileInfo = Jaxer.Dir.map(rootFolder,{pattern:'^.*[12]\..*$',recursive:true}, fileDecorator);   
fileInfo.map(function(i) {Jaxer.Log.info(i)});

// outputs the following in the log:
15:43:05 02/20/2008 [framework.] foo1.txt|0|txt|Tue 
		Feb 19 2008 19:15:04 GMT-0800 (Pacific Standard Time)|c:\rootFolder\subFolder1
15:43:05 02/20/2008 [framework.] foo2.txt|0|txt|Tue 
		Feb 19 2008 19:15:04 GMT-0800 (Pacific Standard Time)|c:\rootFolder\subFolder1
15:43:05 02/20/2008 [framework.] deepFOO1.txt|0|txt|Tue 
		Feb 19 2008 19:15:04 GMT-0800 (Pacific Standard Time)|c:\rootFolder\subFolder3\subFolder3a
15:43:05 02/20/2008 [framework.] deepFOO2.txt|0|txt|Tue 
		Feb 19 2008 19:15:04 GMT-0800 (Pacific Standard Time)|c:\rootFolder\subFolder3\subFolder3a

DirUtils and FileUtils

Jaxer.DirUtils provides access to XPCOM directory/folder utility functions, primarily the following properties:

  1. current: path to the current folder from which the process is running
  2. desktopDir: current user's desktop folder
  3. getHome: current user's home folder
  4. temp: the Jaxer temp directory

Jaxer.FileUtils provides access to XPCOM filesystem functionality, and is the parent class to both Jaxer.Dir and Jaxer.File.