默认情况下上传的文件后缀是.blob
形式的,前端的数据是FormData形式。 我的思路是:
router.post('/upload', upload.single('logo'), function( req, res, next) {
var file = req.file;
console.log('文件类型:%s', file.mimetype);
console.log('原始文件名:%s', file.originalname);
console.log('文件大小:%s', file.size);
console.log('文件保存路径:%s', file.path);
res.status(200).send({
status: 200
});
})
拿到这个文件的时候,去判断这个文件存不存在,如果存在并且是blob形式,那就将这个req.file通过流的形式追加到之前的文件的流的最后。这样有什么问题吗? 在最后一段的时候,文件上传完毕会自动合成一个完整的文件吗? 如果不用multer,应该怎么处理?
当你拿到 req.file 的时候,文件就已经上传完毕,然后经过 multer 处理完毕了,要添加一些操作也应该是在封装好的 upload 文件中添加,因为它负责从 enctype=“multipart/form-data” 封装好的数据流中取出文件名,文件体等,然后做一些额外的处理,例如移动文件,更改上传后的文件名,文件后缀不符合再删除之类的,路由中只处理业务逻辑。
断点续传需要依赖分段上传,将文件分成多个片段,然后在每一个上传的片段中同时携带分段的信息,例如片段的大小,后台根据接收到的文件片段和文件信息来判断片段是否上传完成,如果上传完成,则将其追加到之前上传的片段中。如果上传片段未完成,那么就是断点了,服务器要抛弃这个不完整的片段,并告知客户端,让客户端重新发送这个片段和后面的片段。当然,客户端也要做相应的判断,例如,每上传一个片段,服务器应该返回一个消息,说明上传成功,然后客户端更新状态,如果因为关闭浏览器或者网络中断等原因,那么客户端的状态就不会更新,也就知道自己上传了多少个片段,并在网络恢复后可以继续上传。
还有,和用什么插件去处理文件上传无关,multer 完全可以胜任这个工作
@Hyurl 我每一次上传片段后后台没做特殊处理,只会覆盖文件,不会追加啊
做断点续传还是需要自己实现一些前后端数据交互的。
不能完全依靠multer
@cctv1005s 我是想在multer拿到分段的文件之后,先判断之前有没有分段的文件,有就追加上去
@yuwanlin 肯定要做特殊处理啊,用 fs.appendFile() 方法来追加内容
@Hyurl 我这样追加的啊,然后还是不行,是不是appendFile的第二个参数不能直接是file,而应该是file的流形式?但是我不知道怎么转换
router.post('/upload', upload.single('logo'), function( req, res, next) {
var file = req.file;
fs.exists(filepath, function(exist) {
if(exist) {
fs.appendFile(filepath, file, function() {
console.log('追加完成')
})
}
})
console.log('文件类型:%s', file.mimetype);
console.log('原始文件名:%s', file.originalname);
console.log('文件大小:%s', file.size);
console.log('文件保存路径:%s', file.path);
res.status(200).send({
status: 200
});
})
@yuwanlin 我靠,你要读取文件内容,然后才把文件内容 append 过去好嘛
@Hyurl 那个filepath就是之前存在的文件的路径啊。 我用相同方式如果追加文本文件就可以啊。 另外我发邮件给你了啊。。实在不知道怎么办了
fs.exists(filepath, function(exist) {
if(exist) {
fs.readFile(filepath, function(err, data) {
console.log(data);
fs.appendFile(data, file, function() { // file是multer处理后得到的req.file
console.log(Buffer.isBuffer(data), Buffer.isBuffer(file))
})
})
}
})
老哥,代码现在是这样,console.log(data);
的结果是<Buffer e4 8c 64 71 c...
。下面console的结果是true,false。第一个console的每次结果都是不一样的,但都是Buffer。说明每次读取的文件结果不一样,应该是覆盖了之前的文件吧。这样的话,为什么第二个console的Buffer.isBuffer(file)
是false?
update II 我打印了一下file,我曹,原来是:
{ fieldname: 'logo',
originalname: 'blob',
encoding: '7bit',
mimetype: 'application/octet-stream',
destination: './uploads',
filename: 'logo.blob',
path: 'uploads\\logo.blob',
size: 1024 }
当然不是blob了。那我怎么追加到之前的blob上。。。