egg文件上传
-
formData表单提交的单文件通过 this.ctx.getFileStream 获取数据
前端页面
formData.append(‘myself’, 'some') 必须放到最后,否则ctx.getFileStream()对较大文件取流完成时stream.fields仍然是空的
formData.append('myself', 'some') // 附加字段名
formData.append('file', file) // 文件
egg
-
安装依赖 stream-wormhole
await-stream-ready:顾名思义,能够使用await进行文件的读写操作。 stream-wormhole:在文件上传出现异常时能够把流消耗掉。
例子中没有使用 await-stream-ready
npm i await-stream-ready -S
npm i stream-wormhole -S
-
引入
// const awaitWriteStream = require('await-stream-ready').write;
const sendToWormhole = require('stream-wormhole');
-
获取流
const stream = await ctx.getFileStream();
// stream.filename :上传的文件名称,
// stream.fields:获取附加字段 { myself: 'some' }
-
写入流
// 生成文件名 这里直接用了上传文件的文件名,有需要的可以自己定义 const target = path.join('app/public/uploads', stream.filename); // // 生成文件写入文件流 const writeStream = fs.createWriteStream(target); try { await awaitWriteStream(stream.pipe(writeStream)); } catch (err) { // 必须将上传的文件流消费掉,要不然浏览器响应会卡死 await sendToWormhole(stream); throw err; } -
使用例子
async uploadPicture() {
const { ctx } = this;
// 获取文件对象 此对象包含所有上传携带信息
const stream = await ctx.getFileStream();
const userId = stream.fields.userId
// stream.filename :文件名称,
// stream.fields:附加字段对象
// 结果对象
let result = {};
await new Promise((resolve, reject) => {
// 保存文件,或者使用文件流做别的事情
// ${UPLOAD_PATH}${stream.fieldname}.png 上传地址+文件名
// stream.fieldname 对应前端:name 字段
// stream.fields.userId 是formData附加字段属性
const ws = fs.createWriteStream(`${UPLOAD_PATH}${userId}.${stream.mimeType === 'image/jpeg' ? 'jpg' : 'png'}`);
stream.pipe(ws);
ws.on('finish', () => { // 监听上传成功
resolve();
});
ws.on('error', err => { // 监听上传失败
// 必须将上传的文件流消费掉,要不然浏览器响应会卡死
sendToWormhole(stream);
reject(err);
});
}).then(() => {
result = { data: { url: `${BASE_URL}${userId}.jpeg`} ,status: 200, massage: '上传成功' };
}).catch(err => {
result = { status: 204, massage: err };
});
ctx.body = result;
}
js流操作例子
const fs = require("fs");
// 创建一个可读流
let readerStream = fs.createReadStream('input.txt');
// 创建一个可写流
let writerStream = fs.createWriteStream('output.txt');
// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);
console.log("程序执行完毕");