I need to walk a directory tree where photos are stored to read the photos metadata and write it to database. Since photos metadata are not supported natively in XUL, for a first version I'm just trying to use a command line application to write these data to files, and then read the files to populate the database.
A preliminary version involves this object:
var scanner = {
init: function() {
this.executable = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
this.executable.initWithPath(system.appDir);
this.executable.append('scan');
this.id = 1;
this.regex = {
jpeg: new RegExp('\\.[jJ][pP][eE]?[gG]$', '')
}
},
isImage: function(path) {
return this.regex.jpeg.test(path);
},
readFile: function(path, id) {
let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
process.init(this.executable);
process.run(false, [path, system.selfDir + '/' + id], 2);
},
readDir: function(path) {
if (!this.executable) {
this.init();
}
let dir = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
dir.initWithPath(path);
if (!dir.isDirectory()) {
throw('Not a directory');
}
let files = dir.directoryEntries;
let file;
while (files.hasMoreElements()) {
file = files.getNext().QueryInterface(Ci.nsILocalFile);
if (file.isFile() && this.isImage(file.leafName)) {
this.readFile(file.path, this.id);
this.id = this.id + 1;
}
else if (file.isDirectory()) {
this.readDir(file.path);
}
}
}
};
I copied it fully, but the methods init()
and isImage()
can be ignored. init()
just sets some properties and isImage()
just test if the file name ends with jpg or jpeg.
The method readDir()
reads a directory recursively and calls readFile()
on each image file found. The method readFile()
calls the external tool to actually read the metadata from the file, this data is written in some_config_dir/id, where id is an increasing number.
The problem is that this does not really work, but sort of. I call
scanner.readDir('/home/andrea/Foto');
on a directory containing about 2700 photos, and it stops after about 350. The exact number of photos scanned varies, but it is always between 340 and 355.
I'm puzzled. Can anyone find out why it should stop after a while?
EDIT: I have tried with other numbers of photos. It always stops around 350. Moreover, it does not depend on the particular process: even if I echo a simple number, it does not go past 350 or so.
On the other hand, if I don't call an external process (for instance at each call I create an empty file with the nsIFile interface), it can go well past 350.
Maybe there is a limit to the number of processes that can be spawned at once?
EDIT 2: If I make the processes synchronous, no such problem appears, but of course it will block the interface for quite a while... :-/