node.js中fs.createReadStream与fs.readFile的优缺点是什么? [英] What are the pros and cons of fs.createReadStream vs fs.readFile in node.js?

查看:159
本文介绍了node.js中fs.createReadStream与fs.readFile的优缺点是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究node.js,发现了两种读取文件并通过有线方式发送文件的方法,一旦我确定它存在并使用writeHead发送了正确的MIME类型:

I'm mucking about with node.js and have discovered two ways of reading a file and sending it down the wire, once I've established that it exists and have sent the proper MIME type with writeHead:

// read the entire file into memory and then spit it out

fs.readFile(filename, function(err, data){
  if (err) throw err;
  response.write(data, 'utf8');
  response.end();
});

// read and pass the file as a stream of chunks

fs.createReadStream(filename, {
  'flags': 'r',
  'encoding': 'binary',
  'mode': 0666,
  'bufferSize': 4 * 1024
}).addListener( "data", function(chunk) {
  response.write(chunk, 'binary');
}).addListener( "close",function() {
  response.end();
});

我是否正确假设fs.createReadStream可以提供一个更好的用户体验,如果所讨论的文件很大,例如视频?感觉好像不那么块状.这是真的?我还需要了解其他优点,缺点,警告或陷阱吗?

Am I correct in assuming that fs.createReadStream might provide a better user experience if the file in question was something large, like a video? It feels like it might be less block-ish; is this true? Are there other pros, cons, caveats, or gotchas I need to know?

推荐答案

一种更好的方法,如果只是将数据"连接到"write()",将"close"连接到"end()":

A better approach, if you are just going to hook up "data" to "write()" and "close" to "end()":

// 0.3.x style
fs.createReadStream(filename, {
  'bufferSize': 4 * 1024
}).pipe(response)

// 0.2.x style
sys.pump(fs.createReadStream(filename, {
  'bufferSize': 4 * 1024
}), response)

read.pipe(write)sys.pump(read, write)方法还具有添加流量控制的优点.因此,如果写入流不能尽快接受数据,它将告诉读取流退回,以最大程度地减少缓冲在内存中的数据量.

The read.pipe(write) or sys.pump(read, write) approach has the benefit of also adding flow control. So, if the write stream cannot accept data as quickly, it'll tell the read stream to back off, so as to minimize the amount of data getting buffered in memory.

flags:"r"mode:0666FileReadStream的事实. binary编码已被弃用-如果未指定编码,它将仅与原始数据缓冲区一起使用.

The flags:"r" and mode:0666 are implied by the fact that it is a FileReadStream. The binary encoding is deprecated -- if an encoding is not specified, it'll just work with the raw data buffers.

此外,您还可以添加一些其他功能,使您的文件更加流畅:

Also, you could add some other goodies that will make your file serving a whole lot slicker:

  1. 嗅探req.headers.range,并查看它是否与/bytes=([0-9]+)-([0-9]+)/之类的字符串匹配.如果是这样,您只想从该起点到终点流. (缺少数字表示0或结尾".)
  2. 将stat()调用中的inode和创建时间散列到ETag头中.如果您获得的请求标头具有"if-none-match"匹配的标头,请发送回304 Not Modified.
  3. 对照stat对象上的mtime日期检查if-modified-since标头. 304,如果自提供日期以来未对其进行修改.
  1. Sniff for req.headers.range and see if it matches a string like /bytes=([0-9]+)-([0-9]+)/. If so, you want to just stream from that start to end location. (Missing number means 0 or "the end".)
  2. Hash the inode and creation time from the stat() call into an ETag header. If you get a request header with "if-none-match" matching that header, send back a 304 Not Modified.
  3. Check the if-modified-since header against the mtime date on the stat object. 304 if it wasn't modified since the date provided.

通常,如果可以的话,还发送Content-Length标头. (您正在stat-正在读取文件,所以应该有这个文件.)

Also, in general, if you can, send a Content-Length header. (You're stat-ing the file, so you should have this.)

这篇关于node.js中fs.createReadStream与fs.readFile的优缺点是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆