2016-08-02 18 views
5

Ich habe einen NodeJS (Elektron) Code zum Lesen aller Dateien in einem bestimmten Verzeichnis und Unterverzeichnissen erstellt. Ich möchte nicht zu viele HD-Ressourcen verwenden, weshalb ich eine Verzögerung von 5 ms zwischen den Ordnern verwende.Wie alle Dateien durchlaufen werden, und pausieren und weitermachen

Jetzt meine Frage. Ich möchte das, wenn mein NODE-Prozess aufhört? Ich möchte fortfahren können, wenn es gestoppt wird. Wie soll ich das machen?

Mit anderen Worten: Wie Index des aktuellen Status während des Laufens in allen Dateien und Ordner zu halten, so kann ich die Traversierung fortsetzen, wenn es aufgehört hat.

Danke

Mein Code:

var walkAll=function(options){ 
    var x=0 
    walk(options.dir,function(){}) 
    function walk(dir,callback) { 
     var files=fs.readdirSync(dir); 
     var stat; 
     async.eachSeries(files,function(file,next){ 
     file=dir +'/' + file 
     if (dir.match(/Recycle/)) return next() 
     if (dir.match(/.git/)) return next() 
     if (dir.match(/node_modules/)) return next() 
     fs.lstat(file,function(err,stat){ 
      if(err) return next() 
      if(stat.mode==41398) return next() 
      if (stat.isDirectory()) { 
       setTimeout(function(file){ 
        walk(file,next) 
       }.bind(null,file),5) 
      } 
      else{ 
       x++ 
       if(false || x % 1000===0) console.log((new Date().valueOf()-start)/1000,x,file) 
       next() 
      } 
     }) 
     },function(){ 
     callback() 
     }) 
    } 
} 

walkAll({ 
    dir:'c:/', 
    delay:1000 
}); 
+0

Die erste Frage ist, wie Sie persistance für Ihren Index erhalten wird. Der Index kann dank 'eachSeries' abgeleitet werden, was wie eine" Schleife "funktioniert, so dass Sie eine Variable inkrementieren können. – DrakaSAN

Antwort

2

eine Liste der Unterverzeichnisse halten zu besichtigen und aktualisieren jede Iteration der Liste.

Die Funktion walk im folgenden Beispiel übernimmt einen vorherigen Status und gibt Dateien des nächsten Unterverzeichnisses mit dem nächsten Status zurück.

Sie können den Status speichern, bevor Sie den Prozess stoppen, und dann den gespeicherten Status laden, um die Traversierung beim Neustart fortzusetzen.

function walk(state, readdir) { 
    let files = [], next = []; 
    while (state.length > 0) { 
    try { 
     const current = state.shift() 
     files = readdir(current).map(file => current + '/' + file) 
     next = state.concat(files) 
     break 
    } catch(e) {} 
    } 
    return [next, files] 
} 

function main() { 
    const {writeFileSync: writeFile, readdirSync: readdir} = require('fs') 
    const save = './walk.json' 

    let state 
    try { 
    state = require(save) 
    } catch(e) {} 
    if (!state || state.length < 1) state = ['.'] 

    const [nextState, files] = walk(state, readdir) 
    console.log(files) 
    writeFile(save, JSON.stringify(nextState, null, 2)) 
} 

main() 
+0

Das ganze Problem ist, dass ich die Reise nicht fortsetzen kann, wenn der Prozess neu gestartet wird – Aminadav

2

eine alternative Idee,

var miss = require('mississippi') 
var fs = require("fs") 
var through2 = require("through2") 
var path = require("path") 

function traverseDir(dirPath) { 
    var stack = [path.resolve(dirPath)]; 
    var filesStack = [] 
    return miss.from.obj(function(size, next) { 

    if (filesStack.length) { 
     return next(null, filesStack.shift()) 
    } 

    var self = this; 

    try { 
     while(stack.length) { 
     readADir(stack.pop()).forEach(function (f) { 
      if (f.t=="d") { 
      stack.push(f.p) 
      } 
      filesStack.push(f) 
     }) 
     if (filesStack.length) { 
      return next(null, filesStack.shift()) 
     } 
     } 
     return next(null, null) 
    }catch(ex) { 
     return next(ex) 
    } 
    }) 
} 

function readADir (dir) { 
    return fs.readdirSync(dir) 
    .map(function (f) {return path.join(dir, f)}) 
    .filter(function (f) { return !f.match(/\.git/) }) 
    .filter(function (f) { return !f.match(/Recycle/)}) 
    .filter(function (f) { return !f.match(/node_modules/)}) 
    .map(function (p) { 
     try { 
     var stat = fs.lstatSync(p); 
     if(stat.mode==41398) return null 
     var t = stat.isDirectory() ? "d":"f" 
     return { t: t, p: p } 
     }catch (ex) {} 
     return null 
    }) 
    .filter(function (o) {return o!==null}) 
} 

function loadState(base){ 
    base = path.resolve(base) 
    var state = {base: base, last:null} 
    if (fs.existsSync("state.json")) { 
    state = JSON.parse(fs.readFileSync("state.json")) 
    } else { 
    saveState(state) 
    } 
    return state 
} 

function saveState(state){ 
    fs.writeFileSync("state.json", JSON.stringify(state)) 
} 

var state = loadState("..") 
var sincePath = state.last; 

var filesStream = traverseDir(state.base) 
.on('end', function() { 
    console.log("end") 
}) 
.pipe(through2.obj(function (chunk, enc, next) { 
    if(!sincePath) this.push(chunk) 
    if(chunk.p===sincePath) { 
    sincePath=null 
    } 
    next() 
})) 

var tr = through2.obj(function (chunk, enc, next) { 
    state.last = chunk.p 
    saveState(state) 
    console.log("data %v %j", chunk.t, chunk.p) 
    this.push(chunk) 
    setTimeout(next, 500) 
}).resume() 

require('keypress')(process.stdin); 
process.stdin.on('keypress', function (ch, key) { 
    if(!key) return 
    if (key.name == "c") { 
    console.log("continue") 
    filesStream.pipe(tr) 
    } else if (key.name=="p") { 
    console.log("pause") 
    filesStream.unpipe(tr) 
    } 
}); 

console.log("Press 'c' to start")