在基本目录数组中递归查找子目录
Recursively find sub directories within an array of base directories
出于测试目的,我尝试记录 3 个基本目录中包含多少(子)目录,但结果没有意义。
linux 控制台输出与插件输出,子目录数量不匹配,例如
console.log: recursive: 7
console.info: recursive: time taken = 38ms
console.log: recursive: 7
console.info: recursive: time taken = 41ms
console.log: recursive: 35
console.info: recursive: time taken = 330ms
Total time: 7.571605 seconds
Program terminated successfully.
rob@work:~/git/recursiveDirListingFF$ find /home/rob/Pictures/ -mindepth 1 -type d | wc -l
1
rob@work:~/git/recursiveDirListingFF$ find /home/rob/Music/ -mindepth 1 -type d | wc -l
2
rob@work:~/git/recursiveDirListingFF$ find /home/rob/Downloads/ -mindepth 1 -type d | wc -l
37
任何人都可以看看有什么问题吗?
这是代码,main.js
..
var myBaseDirs = [];
myBaseDirs.push('/home/rob/Pictures');
myBaseDirs.push('/home/rob/Music');
myBaseDirs.push('/home/rob/Downloads');
require("./FileIO").list(myBaseDirs);
FileIO.js
..
var {
Cu
} = require("chrome"),
{
OS
} = Cu.import("resource://gre/modules/osfile.jsm", {});
function compare(a, b) {
if (a.filename < b.filename)
return -1;
if (a.filename > b.filename)
return 1;
return 0;
}
exports.list = function (dirs) {
var audio = [],
dirsTemp = [],
checkedSubdirI = dirs.length - 1,
sTime = new Date().getTime(),
eTime = 0;
for (var w = 0; w < dirs.length; w++) {
dirsTemp.push(dirs[w]);
}
for (var k = 0; k < dirsTemp.length; k++) {
let iterator = new OS.File.DirectoryIterator(dirsTemp[k]);
var promise = iterator.forEach(
function onEntry(entry) {
if (entry.isDir) {
dirsTemp.push(entry);
}
}
);
var onSuc = function onSuccess() {
iterator.close();
if (checkedSubdirI === dirsTemp.length - 1) {
eTime = new Date().getTime();
console.log(dirsTemp.length);
console.info('time taken = ', eTime - sTime + 'ms');
return dirsTemp;
} else {
checkedSubdirI++;
iterator = new OS.File.DirectoryIterator(dirsTemp[checkedSubdirI].path);
promise = iterator.forEach(
function onEntry(entry) {
if (entry.isDir) {
dirsTemp.push(entry);
}
}
);
return promise.then(
onSuc,
onRej
);
}
}
var onRej = function onFailure(reason) {
iterator.close();
eTime = new Date().getTime();
console.info('FAILED reason = ', reason, 'time taken = ', eTime - sTime + 'ms');
throw reason;
}
// Finally, close the iterator
promise.then(
onSuc,
onRej
);
}
};
这被证明是有用的:
//start - helper function
function enumChildEntries(pathToDir, delegate, max_depth, runDelegateOnRoot, depth) {
// IMPORTANT: as dev calling this functiopn `depth` arg must ALWAYS be null/undefined (dont even set it to 0). this arg is meant for internal use for iteration
// `delegate` is required
// pathToDir is required, it is string
// max_depth should be set to null/undefined/<0 if you want to enumerate till every last bit is enumerated. paths will be iterated to including max_depth.
// if runDelegateOnRoot, then delegate runs on the root path with depth arg of -1
// this function iterates all elements at depth i, then after all done then it iterates all at depth i + 1, and then so on
// if arg of `runDelegateOnRoot` is true then minimum depth is -1 (and is of the root), otherwise min depth starts at 0, contents of root
var deferred_enumChildEntries = new Deferred();
var promise_enumChildEntries = deferred_enumChildEntries.promise;
if (depth === undefined || depth === undefined) {
// at root pathDir
depth = 0;
if (runDelegateOnRoot) {
var entry = {
isDir: true,
name: OS.Path.basename(pathToDir),
path: pathToDir
};
var rez_delegate = delegate(entry, -1);
if (rez_delegate) {
deferred_enumChildEntries.resolve(entry);
return promise_enumChildEntries; // to break out of this func, as if i dont break here it will go on to iterate through this dir
}
}
} else {
depth++;
}
if ((max_depth === null || max_depth === undefined) || ( depth <= max_depth)) {
var iterrator = new OS.File.DirectoryIterator(pathToDir);
var subdirs = [];
var promise_batch = iterrator.nextBatch();
promise_batch.then(
function(aVal) {
for (var i = 0; i < aVal.length; i++) {
if (aVal[i].isDir) {
subdirs.push(aVal[i]);
}
var rez_delegate_on_root = delegate(aVal[i], depth);
if (rez_delegate_on_root) {
deferred_enumChildEntries.resolve(aVal[i]);
return promise_enumChildEntries; //to break out of this if loop i cant use break, because it will get into the subdir digging, so it will not see the `return promise_enumChildEntries` after this if block so i have to return promise_enumChildEntries here
}
}
// finished running delegate on all items at this depth and delegate never returned true
if (subdirs.length > 0) {
var promiseArr_itrSubdirs = [];
for (var i = 0; i < subdirs.length; i++) {
promiseArr_itrSubdirs.push(enumChildEntries(subdirs[i].path, delegate, max_depth, null, depth)); //the runDelegateOnRoot arg doesnt matter here anymore as depth arg is specified
}
var promiseAll_itrSubdirs = Promise.all(promiseArr_itrSubdirs);
promiseAll_itrSubdirs.then(
function(aVal) {
deferred_enumChildEntries.resolve('done iterating all - including subdirs iteration is done - in pathToDir of: ' + pathToDir);
},
function(aReason) {
var rejObj = {
promiseName: 'promiseAll_itrSubdirs',
aReason: aReason,
aExtra: 'meaning finished iterating all entries INCLUDING subitering subdirs in dir of pathToDir',
pathToDir: pathToDir
};
deferred_enumChildEntries.reject(rejObj);
}
).catch(
function(aCaught) {
throw aCaught; //throw here as its not final catch
}
);
} else {
deferred_enumChildEntries.resolve('done iterating all - no subdirs - in pathToDir of: ' + pathToDir);
}
},
function(aReason) {
var rejObj = {
promiseName: 'promise_batch',
aReason: aReason
};
if (aReason.winLastError == 2) {
rejObj.probableReason = 'targetPath dir doesnt exist';
}
deferred_enumChildEntries.reject(rejObj);
}
).catch(
function(aCaught) {
throw aCaught;
}
);
} else {
deferred_enumChildEntries.resolve('max depth exceeded, so will not do it, at pathToDir of: ' + pathToDir);
}
return promise_enumChildEntries;
}
// end - helper function
/************ start usage **************/
var totalEntriesEnummed = 0; //meaning total number of entries ran delegate on, includes root dir
var allPaths = [];
function delegate_handleEntry(entry) {
// return true to make enumeration stop
totalEntriesEnummed++;
allPaths.push(entry.path);
console.info('entry:', entry);
}
var pathToTarget = OS.Constants.Path.desktopDir;
var promise_enumEntries = enumChildEntries(pathToTarget, delegate_handleEntry, null /* get all files */, false);
promise_enumEntries.then(
function(aVal) {
console.log('Fullfilled - promise_enumEntries - ', aVal, 'allPaths:', allPaths);
console.info('totalEntriesEnummed:', totalEntriesEnummed)
},
function(aReason) {
console.error('Rejected - promise_enumEntries - ', aReason);
}
).catch(
function(aCatch) {
console.error('Caught - promise_enumEntries - ', aCatch);
}
);
出于测试目的,我尝试记录 3 个基本目录中包含多少(子)目录,但结果没有意义。
linux 控制台输出与插件输出,子目录数量不匹配,例如
console.log: recursive: 7
console.info: recursive: time taken = 38ms
console.log: recursive: 7
console.info: recursive: time taken = 41ms
console.log: recursive: 35
console.info: recursive: time taken = 330ms
Total time: 7.571605 seconds
Program terminated successfully.
rob@work:~/git/recursiveDirListingFF$ find /home/rob/Pictures/ -mindepth 1 -type d | wc -l
1
rob@work:~/git/recursiveDirListingFF$ find /home/rob/Music/ -mindepth 1 -type d | wc -l
2
rob@work:~/git/recursiveDirListingFF$ find /home/rob/Downloads/ -mindepth 1 -type d | wc -l
37
任何人都可以看看有什么问题吗?
这是代码,main.js
..
var myBaseDirs = [];
myBaseDirs.push('/home/rob/Pictures');
myBaseDirs.push('/home/rob/Music');
myBaseDirs.push('/home/rob/Downloads');
require("./FileIO").list(myBaseDirs);
FileIO.js
..
var {
Cu
} = require("chrome"),
{
OS
} = Cu.import("resource://gre/modules/osfile.jsm", {});
function compare(a, b) {
if (a.filename < b.filename)
return -1;
if (a.filename > b.filename)
return 1;
return 0;
}
exports.list = function (dirs) {
var audio = [],
dirsTemp = [],
checkedSubdirI = dirs.length - 1,
sTime = new Date().getTime(),
eTime = 0;
for (var w = 0; w < dirs.length; w++) {
dirsTemp.push(dirs[w]);
}
for (var k = 0; k < dirsTemp.length; k++) {
let iterator = new OS.File.DirectoryIterator(dirsTemp[k]);
var promise = iterator.forEach(
function onEntry(entry) {
if (entry.isDir) {
dirsTemp.push(entry);
}
}
);
var onSuc = function onSuccess() {
iterator.close();
if (checkedSubdirI === dirsTemp.length - 1) {
eTime = new Date().getTime();
console.log(dirsTemp.length);
console.info('time taken = ', eTime - sTime + 'ms');
return dirsTemp;
} else {
checkedSubdirI++;
iterator = new OS.File.DirectoryIterator(dirsTemp[checkedSubdirI].path);
promise = iterator.forEach(
function onEntry(entry) {
if (entry.isDir) {
dirsTemp.push(entry);
}
}
);
return promise.then(
onSuc,
onRej
);
}
}
var onRej = function onFailure(reason) {
iterator.close();
eTime = new Date().getTime();
console.info('FAILED reason = ', reason, 'time taken = ', eTime - sTime + 'ms');
throw reason;
}
// Finally, close the iterator
promise.then(
onSuc,
onRej
);
}
};
这被证明是有用的:
//start - helper function
function enumChildEntries(pathToDir, delegate, max_depth, runDelegateOnRoot, depth) {
// IMPORTANT: as dev calling this functiopn `depth` arg must ALWAYS be null/undefined (dont even set it to 0). this arg is meant for internal use for iteration
// `delegate` is required
// pathToDir is required, it is string
// max_depth should be set to null/undefined/<0 if you want to enumerate till every last bit is enumerated. paths will be iterated to including max_depth.
// if runDelegateOnRoot, then delegate runs on the root path with depth arg of -1
// this function iterates all elements at depth i, then after all done then it iterates all at depth i + 1, and then so on
// if arg of `runDelegateOnRoot` is true then minimum depth is -1 (and is of the root), otherwise min depth starts at 0, contents of root
var deferred_enumChildEntries = new Deferred();
var promise_enumChildEntries = deferred_enumChildEntries.promise;
if (depth === undefined || depth === undefined) {
// at root pathDir
depth = 0;
if (runDelegateOnRoot) {
var entry = {
isDir: true,
name: OS.Path.basename(pathToDir),
path: pathToDir
};
var rez_delegate = delegate(entry, -1);
if (rez_delegate) {
deferred_enumChildEntries.resolve(entry);
return promise_enumChildEntries; // to break out of this func, as if i dont break here it will go on to iterate through this dir
}
}
} else {
depth++;
}
if ((max_depth === null || max_depth === undefined) || ( depth <= max_depth)) {
var iterrator = new OS.File.DirectoryIterator(pathToDir);
var subdirs = [];
var promise_batch = iterrator.nextBatch();
promise_batch.then(
function(aVal) {
for (var i = 0; i < aVal.length; i++) {
if (aVal[i].isDir) {
subdirs.push(aVal[i]);
}
var rez_delegate_on_root = delegate(aVal[i], depth);
if (rez_delegate_on_root) {
deferred_enumChildEntries.resolve(aVal[i]);
return promise_enumChildEntries; //to break out of this if loop i cant use break, because it will get into the subdir digging, so it will not see the `return promise_enumChildEntries` after this if block so i have to return promise_enumChildEntries here
}
}
// finished running delegate on all items at this depth and delegate never returned true
if (subdirs.length > 0) {
var promiseArr_itrSubdirs = [];
for (var i = 0; i < subdirs.length; i++) {
promiseArr_itrSubdirs.push(enumChildEntries(subdirs[i].path, delegate, max_depth, null, depth)); //the runDelegateOnRoot arg doesnt matter here anymore as depth arg is specified
}
var promiseAll_itrSubdirs = Promise.all(promiseArr_itrSubdirs);
promiseAll_itrSubdirs.then(
function(aVal) {
deferred_enumChildEntries.resolve('done iterating all - including subdirs iteration is done - in pathToDir of: ' + pathToDir);
},
function(aReason) {
var rejObj = {
promiseName: 'promiseAll_itrSubdirs',
aReason: aReason,
aExtra: 'meaning finished iterating all entries INCLUDING subitering subdirs in dir of pathToDir',
pathToDir: pathToDir
};
deferred_enumChildEntries.reject(rejObj);
}
).catch(
function(aCaught) {
throw aCaught; //throw here as its not final catch
}
);
} else {
deferred_enumChildEntries.resolve('done iterating all - no subdirs - in pathToDir of: ' + pathToDir);
}
},
function(aReason) {
var rejObj = {
promiseName: 'promise_batch',
aReason: aReason
};
if (aReason.winLastError == 2) {
rejObj.probableReason = 'targetPath dir doesnt exist';
}
deferred_enumChildEntries.reject(rejObj);
}
).catch(
function(aCaught) {
throw aCaught;
}
);
} else {
deferred_enumChildEntries.resolve('max depth exceeded, so will not do it, at pathToDir of: ' + pathToDir);
}
return promise_enumChildEntries;
}
// end - helper function
/************ start usage **************/
var totalEntriesEnummed = 0; //meaning total number of entries ran delegate on, includes root dir
var allPaths = [];
function delegate_handleEntry(entry) {
// return true to make enumeration stop
totalEntriesEnummed++;
allPaths.push(entry.path);
console.info('entry:', entry);
}
var pathToTarget = OS.Constants.Path.desktopDir;
var promise_enumEntries = enumChildEntries(pathToTarget, delegate_handleEntry, null /* get all files */, false);
promise_enumEntries.then(
function(aVal) {
console.log('Fullfilled - promise_enumEntries - ', aVal, 'allPaths:', allPaths);
console.info('totalEntriesEnummed:', totalEntriesEnummed)
},
function(aReason) {
console.error('Rejected - promise_enumEntries - ', aReason);
}
).catch(
function(aCatch) {
console.error('Caught - promise_enumEntries - ', aCatch);
}
);