大文件上传2(后端)

接上一篇大文件上传1(前端),这篇主要是后端实现大文件上传的功能,使用的是node + nestjs

创建file-upload相关文件

nest g module file-upload
nest g controller file-upload
nest g service file-upload

安装依赖

pnpm i @nestjs/platform-express express multer

file-upload.controller.ts 

import { Controller, Post, UploadedFile, UseInterceptors, Body, Res } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { FileUploadService } from './file-upload.service';
import {ApiTags} from '@nestjs/swagger'
import { Response } from 'express';
@ApiTags('上传文件')
@Controller('fileUpload')


export class FileUploadController {
  constructor(private readonly fileUploadService: FileUploadService){}

  @Post()
  @UseInterceptors(FileInterceptor('chunk'))
  async uploadFile(@UploadedFile() file: Express.Multer.File, @Body() body: any,  @Res() res: Response){
    const {hash} = body
    try {
      await this.fileUploadService.saveChunk(file, hash);
      res.status(200).send('Chunk uploaded successfully');
    } catch (error) {
      res.status(500).send('Error uploading chunk');
    }
  }

  @Post('merge')
  async mergeFile(@Body() body:any,  @Res() res: Response){
    const {hash, fileName} = body;
    try {
      await this.fileUploadService.mergeChunks(hash, fileName)

      res.status(200).send('merge successfully');
    } catch (error) {
      res.status(500).send('Error merge chunk');
    }
  }

}

file-upload.module.ts

import { Module } from '@nestjs/common';

import { MulterModule } from '@nestjs/platform-express';

import { FileUploadController } from './file-upload.controller';
import { FileUploadService } from './file-upload.service';
import { diskStorage  } from 'multer'
import { extname } from 'path';
@Module({
  imports: [
    MulterModule.register({
      storage: diskStorage({
        destination:'./uploads',
        filename: (req, file, cb)=> {
          const uniqueSuffix = Date.now() + '-'+Math.round(Math.random()*1E9)
          cb(null, `${uniqueSuffix}${extname(file.originalname)}`)
        }
      })
    })
  ],
  controllers: [FileUploadController],
  providers: [FileUploadService]
})
export class FileUploadModule {}

file-upload.service.ts

import { Injectable } from '@nestjs/common';
import {promises as fs} from 'fs'
import {join} from 'path'

@Injectable()
export class FileUploadService {
  //将上传的文件放在 uploads
  private readonly uploadDir = "./uploads";
  async saveChunk (file: Express.Multer.File, hash: string) {
   const chunkDir = join(this.uploadDir, hash.split('-')[0])
   await fs.mkdir(chunkDir, {recursive: true})
   await fs.rename(file.path, join(chunkDir, hash))

  }

  async mergeChunks (hash: string, fileName: string) {
    const chunkDir = join(this.uploadDir, hash)
    const chunks = await fs.readdir(chunkDir)
    chunks.sort((a,b) => parseInt(a.split('-')[1])-parseInt(b.split('-')[1]))
    const filePath = join(this.uploadDir,fileName)

    for (const chunk of chunks) {
      const chunkPath = join(chunkDir, chunk)
      const data = await fs.readFile(chunkPath)
      await fs.appendFile(filePath, data)
      await fs.unlink(chunkPath)
    }
    await fs.rmdir(chunkDir)
  }

}

启动 nest 就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值