node.js中fs.createReadStream与fs.readFile的优缺点是什么? [英] What are the pros and cons of fs.createReadStream vs fs.readFile in node.js?
问题描述
我正在研究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:0666
是FileReadStream
的事实. 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:
- 嗅探
req.headers.range
,并查看它是否与/bytes=([0-9]+)-([0-9]+)/
之类的字符串匹配.如果是这样,您只想从该起点到终点流. (缺少数字表示0或结尾".) - 将stat()调用中的inode和创建时间散列到ETag头中.如果您获得的请求标头具有"if-none-match"匹配的标头,请发送回
304 Not Modified
. - 对照stat对象上的
mtime
日期检查if-modified-since
标头. 304,如果自提供日期以来未对其进行修改.
- 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".) - 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
. - Check the
if-modified-since
header against themtime
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屋!