Created
February 10, 2010 18:13
-
-
Save creationix/300639 to your computer and use it in GitHub Desktop.
Scan a directory for files and read them all into an object indexed by filename. Async and Sync versions of code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var File = require('file'), | |
Sys = require('sys'), | |
Posix = require('posix'); | |
// Sync api wrapper around some Posix commands | |
// Sells it soul to `wait`. | |
var posix_sync = { | |
readdir: function (path) { | |
return Posix.readdir(path).wait(); | |
}, | |
stat: function (filename) { | |
return Posix.stat(filename).wait(); | |
}, | |
cat: function (filename) { | |
return Posix.cat(filename).wait(); | |
} | |
} | |
// Async api wrapper around some Posix commands | |
// Uses continuable style for cleaner syntax | |
var posix = { | |
readdir: function (path) { return function (next) { | |
Posix.readdir(path).addCallback(next); | |
}}, | |
stat: function (filename) { return function (next) { | |
Posix.stat(filename).addCallback(next); | |
}}, | |
cat: function (filename) { return function (next) { | |
Posix.cat(filename).addCallback(next); | |
}} | |
} | |
// Scan a directory for files | |
// Filter out directories | |
// Read contents of files | |
// Here is the sync version: | |
function scandir_sync(path) { | |
return posix_sync.readdir(path).filter(function (filename) { | |
return posix_sync.stat(filename).isFile(); | |
}).map(function (filename) { | |
return [filename, posix_sync.cat(filename)]; | |
}); | |
} | |
// debug(scandir_sync(__dirname)); | |
// Here is the async version without helpers | |
function scandir1(path) { return function (next) { | |
posix.readdir(path)(function (filenames) { | |
var realfiles = []; | |
var count = filenames.length; | |
filenames.forEach(function (filename) { | |
posix.stat(filename)(function (stat) { | |
if (stat.isFile()) { | |
realfiles.push(filename); | |
} | |
count--; | |
if (count <=0) { | |
var results = []; | |
realfiles.forEach(function (filename) { | |
posix.cat(filename)(function (data) { | |
results.push([filename, data]); | |
if (results.length === realfiles.length) { | |
next(results); | |
} | |
}); | |
}); | |
} | |
}); | |
}); | |
}); | |
}} | |
// Here is the async version with filter and map helpers: | |
function scandir2(path) { return function (next) { | |
posix.readdir(path)(function (filenames) { | |
filter(filenames, function (filename, callback) { | |
posix.stat(filename)(function (stat) { | |
callback(stat.isFile()); | |
}); | |
})(function (filenames) { | |
map(filenames, function (filename, callback) { | |
posix.cat(filename)(function (data) { | |
callback([filename, data]); | |
}); | |
})(next); | |
}); | |
}); | |
}} | |
// Here is the async version with a combined filter and map helper: | |
function scandir3(path) { return function (next) { | |
posix.readdir(path)(function (filenames) { | |
filter_map(filenames, function (filename, callback) { | |
posix.stat(filename)(function (stat) { | |
if (stat.isFile()) { | |
posix.cat(filename)(function (data) { | |
callback([filename, data]); | |
}); | |
} else { | |
callback(); | |
} | |
}); | |
})(next); | |
}); | |
}} | |
scandir3(__dirname)(debug); | |
////////////////////////////////////////////////////////////////////////////// | |
// Utilities // | |
////////////////////////////////////////////////////////////////////////////// | |
// Quick wrapper around puts and inspect | |
function debug() { | |
Sys.puts(Sys.inspect.apply(this, arguments)); | |
} | |
function map(array, callback) { return function (next) { | |
var counter = array.length; | |
var new_array = []; | |
array.forEach(function (item, index) { | |
callback(item, function (result) { | |
new_array[index] = result; | |
counter--; | |
if (counter <= 0) { | |
new_array.length = array.length | |
next(new_array); | |
} | |
}); | |
}); | |
}} | |
function filter(array, callback) { return function (next) { | |
var counter = array.length; | |
var valid = {}; | |
array.forEach(function (item, index) { | |
callback(item, function (result) { | |
valid[index] = result; | |
counter--; | |
if (counter <= 0) { | |
var result = []; | |
array.forEach(function (item, index) { | |
if (valid[index]) { | |
result.push(item); | |
} | |
}); | |
next(result); | |
} | |
}); | |
}); | |
}} | |
function filter_map(array, callback) { return function (next) { | |
var counter = array.length; | |
var new_array = []; | |
array.forEach(function (item, index) { | |
callback(item, function (result) { | |
new_array[index] = result; | |
counter--; | |
if (counter <= 0) { | |
new_array.length = array.length; | |
next(new_array.filter(function (item) { | |
return typeof item !== 'undefined'; | |
})); | |
} | |
}); | |
}); | |
}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment