Node.js Web Server fs.createReadStream vs fs.readFile?



所以我在纯node.js中编写我的Web服务器,仅对promisify使用bluebird。这一直困扰着我一个星期,我无法决定我应该真正使用哪一个。我已经阅读了有关这两个主题的大量帖子,博客和文档,请根据您自己的工作经验回答,谢谢。这是详细的总和和相关问题。

两种方法都经过测试,它们都效果很好。但是我无法测试性能,我只有自己的基本网站文件(html,css,img,小数据库等),而且我从未管理过视频文件和庞大的数据库。

以下是代码部分,可以为您提供基本的想法(如果您真的知道要使用的是哪个,请不要打扰阅读代码,以节省您的时间),此问题与逻辑无关,因此您只能阅读破折号线之间的零件。

关于 fs.createReadStream
优点:适合大型文件,它一次读取一块,保存记忆和管道真的很聪明。
缺点:同步,无法承诺(流是一个不同的概念,要承诺,太难做,不值得)。

//please ignore IP, its just a custom name for prototyping.
IP.read = function (fpath) {
    //----------------------------------------------------
    let file = fs.createReadStream(fpath);
    file.on('error', function () {
        return console.log('error on reading: ' + fpath);
    });
    return file;
    //----------------------------------------------------
};
//to set the response of onRequest(request, response) in http.createServer(onRequest).
IP.setResponse = function (fpath) {
    let ext = path.extname(fpath),
        data = IP.read(fpath);
    return function (resp) {
        //----------------------------------------------------
            //please ignore IP.setHeaders.
        resp.writeHead(200, IP.setHeaders(ext));
        data.pipe(resp).on('error', function (e) {
            cosnole.log('error on piping ' + fpath);
        });
        //----------------------------------------------------
    }
};

关于 fs.readFile
优点:异步可以很容易地承诺,这使得代码非常易于编写(开发)和读取(维护)。还有其他好处,我还没有得到帮助,例如数据验证,安全性等。
缺点:对大文件不利。

IP.read = function (fpath) {
    //----------------------------------------------------
    let file = fs.readFileAsync(fpath);
    return file;
    //----------------------------------------------------
};
//to set the response of onRequest(request, response) in http.createServer(onRequest).
IP.setResponse = function (fpath) {
    const ext = path.extname(fpath);
    return function (resp) {
        //----------------------------------------------------
        IP.read(fpath).then((data) => {
            resp.writeHead(200, IP.setHeaders(ext));
            resp.end(data);
        }).catch((e) => {
            console.log('Problem when reading: ' + fpath);
            console.log(e);
        });
        //----------------------------------------------------
    }
};

这是我的选择:
•简单的方法:将fs.createReadStream用于所有内容。
•正确的方法:仅使用fs.createReadStream用于大文件。
•实用方法:将fs.readFile用于所有事物,直到发生相关问题,然后使用fs.createReadStream

处理这些问题

我的最终决定是使用fs.CreateReadStream用于巨大文件(我将仅为庞大的文件创建一个函数),而fs.ReadFile则用于其他所有内容。这是一个好/正确的决定吗?有更好的建议吗?

P.S.(并不重要):
我真的很喜欢自己构建基础架构,为您提供一个想法,当我实例化服务器时,我可以设置这样的路由,并自定义任何或我想要的任何东西。请不要建议我使用框架:

let routes = [
    {
        method: ['GET', 'POST'],
        uri: ['/', '/home', '/index.html'],
        handleReq: function () {return app.setResp(homeP);}
    },
    {
        method: 'GET',
        uri: '/main.css',
        handleReq: function () {return app.setResp(maincssP);}
    },
    {
        method: 'GET',
        uri: '/test-icon.svg',
        handleReq: function () {return app.setResp(svgP);}
    },
    {
        method: 'GET',
        uri: '/favicon.ico',
        handleReq: function () {return app.setResp(iconP);}
    }
];

,或者我可以自定义并将其放入这样的config.json文件中:

{
"routes":[
    {
        "method": ["GET", "POST"],
        "uri": ["/", "/home"],
        //I will create a function(handleReq) in my application to handle fpath
        "fpath": "./views/index.html"
    },
    {
        "method": "GET",
        "uri": "/main.css",
        "fpath": "./views/main.css"
    },
    {
        "method": "GET",
        "uri": "/test-icon.svg",
        "fpath": "./views/test-icon.svg"
    }
]
}

让我们讨论实际的实际方法。

您不应在生产中的node.js提供静态文件

createReadStreamreadFile都非常有用-createReadStream在大多数情况下更有效,如果您正在处理大量文件(而不是为它们服务),请考虑。

无论如何,您都应该从静态文件服务器中提供静态文件 - 大多数PAAS Web主机会自动为您执行此操作,如果您自己设置环境,您会发现自己在类似IIS之后的逆向透明节点,该节点应该服务于IIS之后静态文件。

仅对于静态文件而言,这是正确的,如果您读取它们并多次转换它们,您的问题变得非常相关。

出于其他目的,您可以安全地使用fs.readFileAsync

我经常使用 readFile来读取文件以缓冲并与它们合作,而 createReadStream可以提高延迟 - 总体而言,您应该获得相似的吞吐量,并且API更易于使用,并且更高级别。

因此,总结

  • 如果您要提供静态文件并关心性能 - 无论如何都不要从Node.js中进行。
  • 如果您将文件转换为流和延迟很重要,请使用createReadStream
  • 否则更喜欢readFile

相关内容

  • 没有找到相关文章

最新更新