使用egg写入文件

一、简单介绍

1、安装
npm i await-stream-ready -S //异步进行读写操作
npm i stream-wormhole -S //在文件上传出现异常时能够把流消耗掉。
2、引入
const awaitWriteStream = require('await-stream-ready').write;
const sendToWormhole = require('stream-wormhole');
3、获取流
const stream = await ctx.getFileStream();
4、生成文件名
const filename = stream.filename; //可以自定义,这里直接使用上传的文件名
5、生成文件路径
const target = path.join('app/public/uploads', filename);//同样可以自己定义放在哪个文件夹,但是要是在public下面的子文件夹
6、生成文件写入文件流
const writeStream = fs.createWriteStream(target);
7、异步写入文件流
try {
  await awaitWriteStream(stream.pipe(writeStream));
} catch (err) {
  await sendToWormhole(stream);
  throw err;
}

二、项目实战

首先写一个基类

// controller/core/base.js文件夹下
const { Controller } = require('egg');
const fs = require('fs');
const path = require('path');
//异步二进制 写入流
const awaitWriteStream = require('await-stream-ready').write;
//管道读入一个虫洞
const sendToWormhole = require('stream-wormhole');
//时间格式化
const dayjs = require('dayjs');

class BaseController extends Controller {
    async uploadFile(category = '') {// category传过来的分开文件格式的目录
        //获取文件流
        const stream = await this.ctx.getFileStream();
        // 基础的目录
        const uploadBasePath = 'app/public/uploads';
        //生成文件名
        const filename = `${Date.now()}${Number.parseInt(Math.random() * 1000)}${path.extname(stream.filename).toLocaleLowerCase()}`;
        //生成文件夹
        const dirname = dayjs(Date.now()).format('YYYY/MM/DD');
        //创建目录
        function mkdirsSync(dirname) {
            if(fs.existsSync(dirname)) { //fs.existsSync检测目录是否存在,存在返回true,反之亦然
                return true;
            } else {
                if(mkdirsSync(path.dirname(dirname))) {//返回 path 的目录名,尾部的文件名会被忽略path.dirname('/目录1/目录2/目录3');返回'/目录1/目录2'
                    fs.mkdirSync(dirname);//fs.mkdirSync同步地创建目录
                    return true;
                }
            }
        }
        mkdirsSync(path.join(uploadBasePath, category, dirname));//path.join,以特定的分隔符将路径连接起来
        // 生成写入路径
        const target = path.join(uploadBasePath, category, dirname, filename);
        // 写入流
        const writeStream = fs.createWriteStream(target);
        try {
            //异步把文件流 写入
            await awaitWriteStream(stream.pipe(writeStream));
        } catch (err) {
            //如果出现错误,关闭管道
            await sendToWormhole(stream);
            return Promise.reject('上传错误')
        }
        return Promise.resolve({
            url: path.join('/public/uploads', category, dirname, filename),
            fields: stream.fields,
        });
    }
}

module.exports = BaseController;

其次在上传文件的控制器中使用

// controller/file/index.js文件夹下,文件夹可自定义

```javascript
'use strict';
const Controller = require('./../core/base');
class FileController extends Controller {
    //上传头像
    async headPortrait() {
        const { ctx } = this;
        // 上传头像的,会在uploads文件夹下有个headPortrait的文件夹下面才是时间文件夹
        try {
            const { url, fields } = await this.uploadFile('headPortrait');
            ctx.body = {
                code: 200,
                message: '上传成功',
                data: {
                    url,
                    fields
                }
            }
        } catch(err) { 
            ctx.body = {
                code: 500,
                message: err,
            }
        }
    }
}

module.exports = FileController;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值