【multer】文件上传模块使用【stream】流的方式来读取数据

您所在的位置:网站首页 node上传文件到本地怎么操作 【multer】文件上传模块使用【stream】流的方式来读取数据

【multer】文件上传模块使用【stream】流的方式来读取数据

2024-06-06 00:43| 来源: 网络整理| 查看: 265

在对应的上传url中,添加文件上传的请求头拦截

app.route('/api/test/uploadFile').post(upload.single("file"), TestController.uploadFile);

这里的upload.single("file")的作用就是将上传的文件以buffer的形式保存到请求参数里面的file属性中。

在这里需要补充一点,如果你的上传需要做权限校验,那权限校验的方法应该写在upload.single("file")后面。由于前端的文件上传的请求头content-type是multipart/form-data,而一般的数据传输的请求头的content-type是application/json。如果先去校验权限的话,会出现无法解析到session数据,无法获取请求头或者request中的数据;如果先调用权限校验方法,则文件上传的数据会因为请求转发而丢失。所以这时候最恰当的做法是,先接收文件的二进制数据,再设置请求头从而获取到request中的数据进行权限校验。

在TestController中用流将数据从字节转换成具体的字符,实现文件读取。

const uploadFile = async (req, res) => { // 先检查文件的buffer是否存在,文件数据有没有保存到Buffer中 if (_.isEmpty(req.file)) { return res.status(400).send({ result: 'error', message: 'file is empty.' }); } let fileData = []; // 定义一个数据,用于保存文件的内容 let len = 0; // 保存流的长度 const bufferStream = new stream.PassThrough(); // 声明一个PassThrough流,将输入字节传到输出 bufferStream.end(req.file.buffer); // 初始化的流,一定为空,这时候让它读取文件的流 // 当有数据,就写入到数组中 bufferStream.on('data', (chunk) => { fileData.push(chunk); len += chunk.length; }); // 这个流到尽头了 bufferStream.on('end', async () => { // 将文件流的内容合并起来,并从字节转成String字符 let content = Buffer.concat(fileData, len).toString(); // 下面做一些具体的读取文件业务操作,你可以调用你的service层,这样会比较合理 ...... // 你需要在这里将响应结果返回,写在外面是没用的 return res.json({result: 'SUCCESS'}); } // 这个只有在流的读写操作错误的时候才会触发 bufferStream.on('error', (error) => { console.log(error); } }

看到这里你可能会觉得很疑惑,为什么我要把流写在这里,不写在service层,还要在流里面将结果返回?因为这个流的事件监听是异步的,这个异步你完全不知道它什么时候返回,更没有用Promise或者await去等待它的结果。事件监听没有回调函数,如果你需要 读取数据 -> 处理数据 -> 返回处理后的数据,也就是你要返回数据给前端,那你就只能将流和事件监听写在Controller这里。

如果不需要什么返回值,我只要你读取数据,然后给我保存就行了,我Controller不等这流的处理结果是什么,先随便响应点什么给前端意思意思就行了。那写在service层就完美了。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3