NestJS+Fastify文件上传仅写入1MiB问题求助
文件上传仅写入1MB内容的排查方案
针对你用NestJS+Fastify结合@fastify/multipart做文件上传时,写入磁盘仅保留1MB左右内容的问题,结合你的代码和环境情况,可能的原因及排查方向如下:
1. @fastify/multipart 默认文件大小限制
@fastify/multipart插件默认对单文件大小限制为1MB,如果没有显式配置更大的限制,插件会自动截断超出部分的文件内容,这会直接导致你写入磁盘的文件只有1MB。
检查你的Fastify插件注册代码,确认是否配置了limits选项:
// NestJS中注册@fastify/multipart时配置更大的文件限制示例 import { NestFactory } from '@nestjs/core'; import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; import fastifyMultipart from '@fastify/multipart'; async function bootstrap() { const app = await NestFactory.create<NestFastifyApplication>( AppModule, new FastifyAdapter(), ); await app.register(fastifyMultipart, { limits: { fileSize: 10 * 1024 * 1024, // 按需设置,示例为10MB }, }); await app.listen(3000); } bootstrap();
2. 请求生命周期提前结束
如果你的控制器方法在文件上传完成前就返回了响应,Fastify会终止当前请求的所有流处理,导致文件写入被截断。
确保控制器逻辑等待文件上传完成后再返回响应:
// 错误示例:未等待上传完成就返回响应 @Post('upload') async upload(@UploadedFile() file: MultipartFile) { this.uploadService.uploadFile('test', file); // 无await,直接返回 return { message: '上传中' }; } // 正确示例:等待上传完成后返回 @Post('upload') async upload(@UploadedFile() file: MultipartFile) { await this.uploadService.uploadFile('test', file); return { message: '上传完成' }; }
3. 流式写入的资源未正确处理
虽然你的writeFileStream函数做了基础错误监听,但可以从以下几点排查:
- 检查磁盘权限:容器挂载目录的权限可能被意外修改,导致写入到一定大小后无法继续
- 调试流接收情况:在
file.file流上添加data事件监听,确认是否真的只收到了1MB的数据
// 调试用:打印每个数据块的字节数 file.file.on('data', (chunk) => { console.log(`收到数据块:${chunk.length}字节`); });
4. 错误使用Fastify Multipart的文件对象
@fastify/multipart默认会将文件写入临时目录,通过filepath字段暴露临时文件路径。如果你直接读取file.file流,可能因插件内部的临时文件处理逻辑导致流被提前关闭。可以尝试直接复制临时文件到目标目录:
import { copyFileSync } from 'fs'; async uploadFile(path, file): Promise<void> { const normalPath = resolve(`${process.cwd()}/uploads/files/${path}/${file.filename}`); // 直接复制插件生成的临时文件 copyFileSync(file.filepath, normalPath); }
内容的提问来源于stack exchange,提问作者Vladimir
相关产品推荐
相关产品推荐

