2012-01-09 9 views
34

Sto costruendo un server super semplice nel nodo e nel mio ascoltatore onRequest sto provando a determinare se dovrei servire un file statico (fuori dal disco) o qualche json (probabilmente estratto da mongo) in base al percorso in request.url.Il modo più veloce per verificare l'esistenza di un file in NodeJs

Attualmente sto provando a impostare prima il file (perché uso mtime altrove) e se ciò non fallisce, leggo il contenuto dal disco. Qualcosa di simile a questo:

fs.stat(request.url.pathname, function(err, stat) { 
    if (!err) { 
     fs.readFile(request.url.pathname, function(err, contents) { 
      //serve file 
     }); 
    }else { 
     //either pull data from mongo or serve 404 error 
    } 
}); 

Oltre cacheing il risultato della fs.stat per la request.url.pathname, c'è qualcosa che potrebbe accelerare questo check-up? Ad esempio, sarebbe altrettanto veloce vedere se si verificano errori fs.readFile anziché stat? O usando fs.createReadStream invece di fs.readFile? O potrei potenzialmente verificare il file usando qualcosa in child_process.spawn? Fondamentalmente voglio solo assicurarmi di non passare troppo tempo a messare w/fileio quando la richiesta deve essere inviata a mongo per i dati ...

Grazie!

+4

ho sempre usato 'stat' o' statSync' seconda mie esigenze (ad esempio ' statSync' in config), ma immagino che sarebbe tecnicamente più veloce fare 'readfile' e rilevare un errore (anche se l'errore di cattura è ___very__ pesante in JS, quindi potrei sbagliarmi). In generale, però, preferirei usare 'stat' semplicemente perché è più pulito che intenzionalmente lanciare un errore. Evita 'child_process' in generale dato che' node' sta facendo una push sui sistemi Windoze e qualsiasi codice che lo usa si romperà. –

+1

@Lite Byte dovresti accettare seriamente la risposta data da DeadDEnD ... –

risposta

56
var fs = require('fs'); 

fs.exists(file, function(exists) { 
    if (exists) { 
    // serve file 
    } else { 
    // mongodb 
    } 
}); 
+12

Solo FYI, 'path.exists()' è stato deprecato nelle versioni successive del Nodo. Ora è 'fs.exists()'. – MikeSchinkel

+0

Esatto. Grazie. – fent

+7

Si noti che 'file' può essere effettivamente una directory, un collegamento simbolico, una pipe, ecc. Per trovare solo i file, si può usare qualcosa come' fs.stat (file, funzione (err, stats) {if (! Err && stats. isFile()) {// serve} else {// qualcos'altro}}); 'Ma anche questo non garantisce che tu possa effettivamente leggere quel file. Le autorizzazioni potrebbero essere errate o il file potrebbe essere rimosso prima ancora di leggerlo. A seconda del contesto, un modo per affrontare il problema potrebbe essere semplicemente provare a leggere il file e poi fare qualcos'altro se fallisce. – tuomassalo

2

Non penso che dovresti preoccuparti di questo, ma piuttosto come puoi migliorare il meccanismo di memorizzazione nella cache. fs.stat è davvero ok per il controllo dei file, farlo in un altro processo figlio probabilmente ti rallenterebbe piuttosto che aiutarti.

Collegare implementato lo staticCache() middleware a pochi mesi fa, come descritto in questo post del blog: http://tjholowaychuk.com/post/9682643240/connect-1-7-0-fast-static-file-memory-cache-and-more

A meno di recente Used (LRU) della cache algo è implementata attraverso l'oggetto Cache, semplicemente ruotare gli oggetti della cache mentre vengono colpiti. Questo significa che gli oggetti sempre più popolari mantengono le loro posizioni mentre altri vengono espulsi dallo stack e raccolti.

Altre risorse:
http://senchalabs.github.com/connect/middleware-staticCache.html
The source code for staticCache

2

questo frammento possono aiutare a

fs = require('fs') ; 
var path = 'sth' ; 
fs.stat(path, function(err, stat) { 
    if (err) { 
     if ('ENOENT' == err.code) { 
      //file did'nt exist so for example send 404 to client 
     } else { 
      //it is a server error so for example send 500 to client 
     } 
    } else { 
     //every thing was ok so for example you can read it and send it to client 
    } 
}); 
Problemi correlati