2012-01-09 21 views
34

Estoy construyendo un servidor super simple en un nodo y en mi oyente onRequest estoy tratando de determinar si debo servir un archivo estático (fuera del disco) o algo json (probablemente extraído de mongo) según la ruta en request.url.La forma más rápida de verificar la existencia de un archivo en NodeJs

Actualmente estoy tratando de establecer el archivo primero (porque uso mtime en otro lugar) y si eso no falla, entonces leo los contenidos del disco. Algo como esto:

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 
    } 
}); 

Aparte de cache el resultado de fs.stat para la request.url.pathname, ¿hay algo que podría acelerar este chequeo? Por ejemplo, ¿sería tan rápido para ver si fs.readFile errores en lugar de stat? ¿O usando fs.createReadStream en lugar de fs.readFile? ¿O podría verificar el archivo usando algo en child_process.spawn? Básicamente solo quiero asegurarme de no pasar más tiempo jugando w/fileio cuando la solicitud debe enviarse a mongo para obtener datos ...

¡Gracias!

+4

Siempre he usado '' stat' o statSync' en función de mis necesidades (por ejemplo ' statSync' in config), pero supongo que técnicamente sería más rápido hacer 'readfile' y atrapar un error (aunque la captura de errores es ___muy___ pesada en JS, así que podría estar equivocado). En general, sin embargo, preferiría usar 'stat' simplemente porque es más limpio que lanzar un error intencionalmente. Evite 'child_process' en general ya que' node' está presionando en los sistemas Windoze y cualquier código que lo use se romperá. –

+1

@Lite Byte, debe aceptar seriamente la respuesta dada por DeadDEnD ... –

Respuesta

56
var fs = require('fs'); 

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

Solo FYI, 'path.exists()' ha quedado en desuso en versiones posteriores de Node. Ahora es 'fs.exists()'. – MikeSchinkel

+0

Eso es correcto. Gracias. – fent

+7

Tenga en cuenta que 'archivo' puede ser realmente un directorio, enlace simbólico, canalización, etc. Para encontrar solo archivos, puede usar algo como' fs.stat (archivo, función (err, stats) {if (! Err && stats. isFile()) {// serve} else {// algo más}}); 'Pero incluso eso no garantiza que puedas leer ese archivo. Los permisos pueden ser incorrectos, o el archivo puede simplemente eliminarse antes de que realmente lo lea. Dependiendo del contexto, una forma de abordar el problema podría ser simplemente intentar leer el archivo y luego hacer otra cosa si falla. – tuomassalo

2

No creo que deba preocuparse por eso, sino cómo puede mejorar el mecanismo de almacenamiento en caché. fs.stat está realmente bien para la comprobación de archivos, hacer eso en otro proceso secundario probablemente lo desacelere en lugar de ayudarlo aquí.

Conectar implementó el staticCache() middleware hace unos meses, como se describe en esta entrada del blog: http://tjholowaychuk.com/post/9682643240/connect-1-7-0-fast-static-file-memory-cache-and-more

A menos recientemente-Used (LRU) caché algo se implementa a través del objeto Cache, simplemente rotar objetos de caché a medida que se golpean. Este significa que los objetos cada vez más populares mantienen sus posiciones mientras que otros se sacan de la pila y se recoge la basura.

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

2

este fragmento puede ayudarle 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 
    } 
}); 
Cuestiones relacionadas