1

我真的在为 connect-busboy 和流式写作而苦苦挣扎。问题是我想做一些文件验证,但如果不先处理数据就无法做到这一点,而且似乎我必须在处理它时将其写入文件。

当数据进入并且我遇到文件大小或文件类型限制等错误时,我拒绝了请求,但文件的一部分已经写入磁盘。我真的很想省略写入直到最后,或者可能将其暂存到内存缓冲区中。

此代码将拒绝无效的文件类型和大小限制,但它始终首先创建写入流并将文件通过管道传输到其中。我真正想做的是移动“file.pipe(fstream);” 进入 file.on('end',... 回调,但这当然不起作用,因为它必须在它进入时写入。所以看起来我需要先将它写入暂存缓冲区,然后在结束将它刷新到一个真实文件。或者我可以写入一个临时文件,并在出错时删除该文件,但这似乎更加hacky和脆弱。对于这个看似常见的问题,最佳实践是什么?

saveFiles: function(request, options) {

return new Promise(function(resolve, reject) {

  var fstream;
  var totalData = 0;
  request.pipe(request.busboy);
  var fileIds = [];
  var assets = {'assets': {}};
  request.busboy.on('file', function(fieldname, file, originalName, encoding, contype) {
    file.on('limit', function() {
      var limitBytes = request.busboy.opts.limits.fileSize;
      var limitMB = Math.round((limitBytes / 1048576) * 100) / 100;
      return reject({errorMsg: 'Files exceeded the size limit of ' + limitMB + 'MB'});
    });
    file.on('data', function(data) {
      if (totalData === 0) {
        var type = fileType(data);
        if(type) {
          if (request.busboy.opts.limits.validFileTypes.indexOf(type.ext) === -1) {
            return reject({errorMsg: 'Invalid file type "' + type.ext + '"'}); 
          }
        }
        else {
          return reject({errorMsg: 'Invalid file type'}); 
        }
      }
      totalData += data.length;
    });
    var fileId = uuid.v1(); // used for file name on server
    var parts = originalName.split('.');
    var extension = parts[parts.length - 1].toLowerCase();
    var fileName = fileId + '.' + extension;

    fstream = fs.createWriteStream(__assets + fileName);
    file.pipe(fstream);

    file.on('end', function() {
      assets['assets'][fileId] = {
        fileName: fileId + '.' + extension,
        originalName: originalName
      };
    });

  });
  request.busboy.on('finish', function(){
    resolve(assets);
  });
});

}
4

0 回答 0