在我的项目中,客户端将请求从具有id的服务器下载文件。我必须执行以下操作:
我使用以下代码检查文件并发送响应。
fs.exists(filename, function(exists) {
if (!exists) {
res.writeHead(404, '', {
"Content-Type" : "text/plain"
})
res.write("404 Not Found\n");
res.end();
return;
}
fs.readFile(filename, "binary", function(err, file) {
if (err) {
res.writeHead(500, '', {
"Content-Type" : "text/plain"
})
res.write(err + "\n");
res.end();
return;
}
res.setHeader("Pragma", "public");
res.setHeader("Cache-Control: private, max-age=3600");
res.setHeader("Transfer-Encoding: chunked");
res.setHeader("Range: chunked");
res.writeHead(200, '', {
"Content-Type" : contentType
});
res.write(file, "binary");
res.end(file, "binary");
});
});
在几毫秒内,客户端将请求数百个文件。支持的文件类型是图像,音频或视频。
当文件夹中有大量文件时,node.js花费了太多时间来下载文件。如何提高性能?
答案 0 :(得分:5)
我会推荐一些东西。
您不应该使用'binary'
。根本不要给出编码。通过添加编码,您将使节点执行大量额外工作以将文件的Buffer
对象转换为二进制编码的string
。当您使用write
再次呼叫'binary'
时,这意味着节点必须以相反的方式执行相同的操作。此外,您将文件传递给end
和write
,这意味着您下载的每个文件都将包含两次文件数据。
我建议不要使用readFile
。由于readFile
在您的file
变量中将整个文件内容传递给您,您需要节点将文件的全部内容加载到RAM中,这意味着它需要分配大量缓冲区然后连接他们,这是不必要的工作。
没有理由单独使用exists
,因为如果您尝试打开不存在的文件,错误会告诉您,因此首先检查只是额外的工作。
此外,Transfer-encoding
标题将自行设置,您无需执行此操作。
这样的事情应该更快:
fs.createReadStream(filename)
.on('error', function(err){
if (err.code === 'ENOENT'){
res.writeHead(404, {
'Content-type': 'text/plain'
});
res.end('404 Not Found\n');
} else {
res.writeHead(500, {
'Content-type': 'text/plain'
});
res.end(err + '\n');
}
})
.on('open', function(){
res.writeHead(200, {
'Pragma': 'public',
'Cache-Control': 'private, max-age=3600',
'Content-type': contentType
});
})
.pipe(res);