multer断点续传应该怎么处理
发布于 3 年前 作者 yuwanlin 2745 次浏览 来自 问答

默认情况下上传的文件后缀是.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,应该怎么处理?

11 回复

当你拿到 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就是之前存在的文件的路径啊。 我用相同方式如果追加文本文件就可以啊。 另外我发邮件给你了啊。。实在不知道怎么办了

@Hyurl

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上。。。

回到顶部