【问题标题】:Fastest way to check for existence of a file in NodeJs在 NodeJs 中检查文件是否存在的最快方法
【发布时间】:2012-01-09 01:04:44
【问题描述】:

我正在节点中构建一个超级简单的服务器,在我的 onRequest 侦听器中,我试图根据路径确定我是否应该提供静态文件(磁盘外)或一些 json(可能从 mongo 中提取) request.url.

目前我正在尝试先统计文件(因为我在其他地方使用 mtime),如果没有失败,那么我从磁盘读取内容。像这样的:

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

除了为request.url.pathname 缓存fs.stat 的结果之外,还有什么可以加快此检查的速度吗?例如,查看fs.readFile 是否出错而不是stat 是否一样快?或者使用fs.createReadStream 而不是fs.readFile?或者我可以使用child_process.spawn 中的内容检查文件吗?基本上,我只是想确保在将请求发送到 mongo 以获取数据时,我不会花费任何额外的时间来处理 fileio...

谢谢!

【问题讨论】:

  • 我一直根据我的需要使用statstatSync(例如配置中的statSync),但我猜从技术上讲,使用readfile 和捕获错误(尽管错误捕获在 JS 中 very 很重,所以我可能错了)。不过,总的来说,我更喜欢使用stat,因为它比故意抛出错误更干净。通常避免使用child_process,因为node 正在推动Windoze 系统,使用它的任何代码都会中断。
  • @Lite Byte 你应该认真接受 DeadDEnD 给出的答案...

标签: performance node.js


【解决方案1】:
var fs = require('fs');

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

【讨论】:

  • 仅供参考,path.exists() 在更高版本的 Node.js 中已被弃用。现在是fs.exists()
  • 请注意file实际上可以是目录、符号链接、管道等。要仅查找文件,您可以使用fs.stat(file, function(err, stats) { if(!err && stats.isFile()) { //serve } else { //something else } });之类的东西,但即使这样也不能保证您实际上可以阅读该文件。权限可能是错误的,或者文件可能只是在您实际阅读之前被删除。根据上下文,解决问题的一种方法可能是尝试读取文件,然后在失败时执行其他操作。
  • 来自节点文档:“fs.exists() 是不合时宜的,仅出于历史原因而存在。几乎没有理由在您自己的代码中使用它。fs.exists() 将是已弃用。”使用它有一些正当的理由,那么应该用什么来代替它呢?
  • 花了我一段时间,但我认为正确的模式是先尝试提供静态文件,然后如果由于某种原因失败(文件不存在),您可以回退到其他方法.这巧妙地避免了检查文件是否存在。
  • 现在 fs.exists() 已被弃用。请改用fs.stat()fs.access()
【解决方案2】:

我认为您不应该担心这一点,而应该担心如何改进缓存机制。 fs.stat 确实可以用于文件检查,在另一个子进程中这样做可能会减慢您的速度,而不是在这里帮助您。

Connect 几个月前实现了 staticCache() 中间件,如本文所述:http://tjholowaychuk.com/post/9682643240/connect-1-7-0-fast-static-file-memory-cache-and-more

最近最少使用 (LRU) 缓存算法是通过 Cache 对象,在缓存对象被命中时简单地旋转它们。这 意味着越来越受欢迎的对象保持其位置,同时 其他人被推出堆栈并收集垃圾。

其他资源:
http://senchalabs.github.com/connect/middleware-staticCache.html
The source code for staticCache

【讨论】:

    【解决方案3】:

    这个sn-p可以帮助你

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

    【讨论】:

      【解决方案4】:

      如果您想使用 express 提供文件,我建议只使用 express 的 sendFile 错误处理程序

      const app = require("express")();
      
      const options = {};
      options.root = process.cwd();
      
      var sendFiles = function(res, files) {
        res.sendFile(files.shift(), options, function(err) {
          if (err) {
            console.log(err);
            console.log(files);
            if(files.length === 0) {
              res.status(err.status).end();
            } else {
              sendFiles(res, files)
            }
          } else {
            console.log("Image Sent");
          }
        });
      };
      
      app.get("/getPictures", function(req, res, next) {
        const files = [
          "file-does-not-exist.jpg",
          "file-does-not-exist-also.jpg",
          "file-exists.jpg",
          "file-does-not-exist.jpg"
        ];
      
        sendFiles(res, files);
      
      });
      
      app.listen(8080);
      
      

      如果该文件不存在,那么它将转到自行发送的错误。 我在这里做了一个github repo https://github.com/dmastag/ex_fs/blob/master/index.js

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-06
        • 2023-03-22
        • 2017-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多