本篇内容主要讲解“Node.Js怎么实现sendfile数据传输”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node.Js怎么实现sendfile数据传输”吧!
首先我们看一下sendfile的好处是什么。
sendfile() copies data between one file descriptor and another. Because this copying is done within the kernel, sendfile() is more efficient than the combination of read(2) and write(2), which would require transferring data to and from user space.
我们看到sendfile通过把内核完成数据的传输,减少了内核和用户层的数据复制,从而提高了效率。下面我们通过napi写一个addon来实现这个功能。
#include <sys/sendfile.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <node_api.h> static napi_value copyFile(napi_env env, napi_callback_info info) { size_t argc = 3; napi_value args[3]; // 拿到js层的入参,这里是三个 napi_get_cb_info(env, info, &argc, args, NULL, NULL); int fd1; int fd2; int len; // js传入的是一个数字,v8转成了对象,这里再次把入参转成int型 napi_get_value_int32(env, args[0], &fd1); napi_get_value_int32(env, args[1], &fd2); napi_get_value_int32(env, args[2], &len); int writed = sendfile(fd2, fd1, 0,len); napi_value ret; napi_create_int32(env, writed, &ret); return ret; } napi_value Init(napi_env env, napi_value exports) { napi_value func; // 创建一个函数并且设置为exports对象的getArray属性的值 napi_create_function(env, NULL, NAPI_AUTO_LENGTH, copyFile, NULL, &func); napi_set_named_property(env, exports, "copyFile", func); return exports; } NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
下面我们看看怎么使用。首先用这个addon来复制文件,类似Node.js的copyyFile
const fs= require('fs'); const { copyFile } = require('./build/Release/sendfile.node'); const { O_WRONLY, O_CREAT, } = fs.constants; async function test() { const [fd1, fd2] = await Promise.all([openFile('1.txt', 'r'), openFile('2.txt', O_WRONLY | O_CREAT)]); const { size } = await getFileInfo(fd1); console.log(copyFile(fd1, fd2, size)); fs.close(fd1, () => {}); fs.close(fd2, () => {}); } function openFile(filename, mode) { return new Promise((resolve, reject) => { fs.open(filename, mode, (err, fd) => { if (err) { reject(err); } else { resolve(fd); } }); })} function getFileInfo(fd) { return new Promise((resolve, reject) => { fs.fstat(fd, (err, stat) => { if (err) { reject(err) }else { resolve(stat); } }); }) } test();
执行上面代码,我们可以看到文件会成功复制2.txt。接着我们再来试一下网络IO的场景。
const fs= require('fs'); const http = require('http'); const { copyFile } = require('./build/Release/sendfile.node'); const server = http.createServer(async (req, res) => { const fd = await openFile('1.txt', 'r'); const { size } = await getFileInfo(fd); const ret = copyFile(fd, res.socket._handle.fd, size); res.socket.end(); }).listen(8002); const { O_WRONLY, O_CREAT, } = fs.constants; function openFile(filename, mode) { return new Promise((resolve, reject) => { fs.open(filename, mode, (err, fd) => { if (err) { reject(err); } else { resolve(fd); } }); })} function getFileInfo(fd) { return new Promise((resolve, reject) => { fs.fstat(fd, (err, stat) => { if (err) { reject(err) }else { resolve(stat); } }); })}
以上代码首先启动一个http服务器,然后收到请求的时候,通过addon调用sendfile给前端返回对应的内容,最后关闭连接。结果如下。
到此,相信大家对“Node.Js怎么实现sendfile数据传输”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!