Let’s start writing the code, first we include the walker.js and options.js file:
const walkerClass = require('./walker.js'), OPT = require ('./options.js');
Next, we create some variables to store some information, like:
let includedDirs=[], excludedDirs=[], totalProcessedFiles=0, totalProcessedDirs=0;
The includedDirs
and excludedDirs
arrays will store the paths received from the parent (renderer.js). The totalProcessedFiles
and totalProcessedDirs
will count the processed files and dirs.
Receiving messages from walker.js
Next, we’ll create a new instance of FileWalker class and respond to its event by creating the callback functions:
let walker = new walkerClass(); walker.on('error', cbError); walker.on('file', cbFile); walker.on('dir', cbDir); walker.on('hash', cbHash); walker.on('unknown', cbUnknow); walker.on('pause', cbPause); walker.on('resume', cbResume); walker.on('duplicate',cbDuplicate); walker.on('done', cbDone);
The explanation of each callback function is:
FileWalker.on('error', cbError)
Run thecbError
function If error occurred while scanning or reading the entry (dir or file)FileWalker.on('file', cbFile)
RuncbFile
function when a file entry found.FileWalker.on('dir', cbDir)
ExecutecbDir
function when a directory entry found.FileWalker.on('unknown', cbUnknown)
RuncbUnknown
function if an unknown error occurred while scanning or reading the entry.FileWalker.on('hash', cbHash)
ExecutecbHash
function when a Hash generated for a file.FileWalker.on('duplicate', cbDuplicate)
RuncbDuplicate
function when a duplicate file entry found.FileWalker.on('pause', cbPause)
RuncbPause
function when FileWalker paused.FileWalker.on('resume', cbResume)
RuncbResume
function when FileWalker resumed.FileWalker.on('done', cbDone)
Run thecbDone
function when FileWalker finished scanning.
Receiving messages from renderer.js
The walkerHelper.js process will receive messages in an object form from its parent:
process.on('message',(m)=>{ switch (m.walker){ case OPT.START: start(m.dirs); break; case OPT.PAUSE: walker.pause(); break; case OPT.RESUME: walker.resume(); break; case OPT.RESET: reset(); break; } })
The process.on
event listen IPC messages from parent. We use switch case statement to filter out the received message. The start function will execute if the received message contains OPT.START
value. The start function will store the files in includedDirs
and excludedDirs
array and start the FileWalker
.
The OPT.PAUSE
and OPT.RESUME
will use to pause and resume the FileWalker.
Let’s create the start
and reset
functions later in this tutorial.
start function
When a user click on the start button, the renderer.js file sends OPT.START
message along with a dirs
object. The dirs
object is a nested object which contains dir
objects, each dir
object has two properties: path
and isIncluded
. If the isIncluded
property is true then the dir path added to includedDirs
array otherwise it added to excludedDirs
array.
function start(dirs){ reset(); for (let i in dirs){ let dir = dirs[i]; if (dir.isIncluded) includedDirs.push(dir.path); else excludedDirs.push(dir.path); } //add to walker's queue walker.addToQueue(includedDirs); //walker's callback function to filter dirs walker.filterDir((dir,stat)=>{ return excludedDirs.indexOf(dir) !== -1 }); walker.next(); let obj = { walker:OPT.STARTED } process.send(obj); }
Then we pass the includedDirs
array to walker.addToQueue
method. Next, the walker.filterDir
callback method compare the each dir, found on the file-system, with excludedDirs
array. The matched dir path will not scan.
The walker.next();
starts the file system scanning for next available entry from the queue. Then we send a OPT.STARTED
message to renderer.js to inform that walker started and scanning the received directories.
reset function
The reset function resets the FileWalker
and the following variables:
function reset(){ walker.reset(); includedDirs=[], excludedDirs=[], totalProcessedFiles=0, totalProcessedDirs=0; }
It is useful when a user want to start a new scanning and cancel the existing process.
Creating FileWalker callback functions
cbError function
We can use this function to log error messages.
function cbError(err,entry,stat){ //The entry has some issues console.log(err) }
cbUnknown function
An unknown error occurred, it usually receive on Windows os, when walker try to scan system or protected files or dirs.
function cbError(entry,stat){ //The entry has some issues console.log(err) }
cbFile function
This function triggered when a file found, we’ll use this function to count processed files:
function cbFile(entry,stat){ totalProcessedFiles++; /*You can send file information to parent if necessary. let obj = { walker: OPT.FILE, file: entry, stat: stat, totalProcessedFiles:totalProcessedFiles } process.send(obj)*/ }
cbDir function
This function will trigger when a director found while scanning file system. The process.send
method send an object to renderer.js
, which contains the current working directory along-with its stat and total processed dirs.
function cbDir(entry,stat){ totalProcessedDirs++ let obj = { walker: OPT.DIR, dir: entry, stat: stat, totalDirs:totalProcessedDirs } process.send(obj); }
cbHash function
cbHash function returns file, its stat and its generated hash. We don’t need it at this moment, we’ll use it when a duplicate file found.
function cbHash(file,stat,hash){ //We'll not use this cb //For demonstration purpose only }
cbPause and cbResume functions
These methods trigger when FileWalker paused or resume. We’ll send a message OPT.PAUSED
or OPT.RESUMED
to parent, renderer.js, to inform FileWalker has been paused or resumed.
function cbPause(){ let obj = { walker:OPT.PAUSED } process.send(obj); } function cbResume(){ let obj = { walker: OPT.RESUMED } process.send(obj); }
cbDuplicate function
Here we’ll receive the duplicate files. This method has four parameters:
- files (array)
- size (integer)
- ext (string)
- hash (stirng)
function cbDuplicate(files,size,ext,hash){ let df = JSON.stringify( {size:size, id:hash+ext+size, files:files} ); let obj = { walker: OPT.WEBVIEW, addRows: 'addRows('+df+')' } process.send(obj); }
We’ll send these file to renderer.js to display on GUI. We’ll use chrome’s webview
feature to display duplicate files in index.html file.
cbDone function
This method triggered when FileWalker finished scanning the provided directories.
function cbDone(){ let obj = { walker: OPT.DONE, totalFiles:totalProcessedFiles, totalDirs: totalProcessedDirs } process.send(obj); }
This function send OPT.DONE
message to renderer.js. The message properties are:
totalFiles
the number of files readtotalDirs
the number of directories scanned
Next, we’ll re-create the rendrer.js file so it can communicate properly with walkerHelper.js by establishing the IPC channel between them.
Click here to download walkerHelper.js file.