2015-07-02 147 views
3

框架:node.js的/ express.js /打杂/ GridFS的流(MongoDB的)node.js的上传和下载pdf文件

我使用打杂上传文件,然后使用GridFS的流存储mongodb网格中的文件。

   req.pipe(req.busboy); 
       req.busboy.on('file', function (bus_fieldname, bus_file, bus_filename) { 

       var writestream = gfs.createWriteStream({ 
        filename: bus_filename, 
       }); 

       bus_file.pipe(writestream); 

       writestream.on('close', function (file) { 
        res.redirect('/xxxxx/'); 
       }); 
      }); 

下载非常简单:使用GridFS的流的createReadStream我读了MongoDB的内容,然后使用下面的代码将其发送给浏览器。

  gfs.findOne({_id: attachmentid}, function (err, file) { 
      if (err || !file){ 
       res.send(404); 
      }else{ 
       var fileName = file.filename; 
       var readstream = gfs.createReadStream({_id: attachmentid}); 
       var buffer = ""; 
       readstream.on("data", function (chunk) { 
        buffer += chunk; 
       }); 

       // dump contents to buffer 
       readstream.on("end", function() { 
        res.set("Content-Disposition","attachment; filename=" + fileName); 
        res.send(buffer); 
       }); 

      } 

问题:当我上传90KB pdf文件,其上传的罚款。我看到mongodb中的大小是正确的。但是当我下载时,下载的文件的文件大小约为165kb。有一个不匹配。这不会发生在文本文件中。当然,它与数据类型有关。

任何人都可以请帮忙吗?

回答

3

将gfs读取流直接传递给响应。这对我来说很有用

res.set("Content-Disposition","attachment; filename=" + fileName); 
var readstream = gfs.createReadStream({_id: attachmentid}); 
readstream.pipe(res); 
+0

谢谢...伟大工程。 – user3658423

1

就像Sasikanth说的那样,你可以用管道解决问题,这是最好的方法。

但是,如果您想知道您当前的方法有什么问题,那么我建议您阅读Buffer documentation.You将您的变量命名为buffer,但分配字符串。

然后在您的data回调中,您正在使用缓冲区添加字符串。当你这样做时,chunk缓冲区使用它的toString()方法转换为字符串。所以你的二进制数据被转换为utf8编码的字符串,这里出错了。由于utf8是多字节编码,输出尺寸变大(我不知道这种转换的确切机制)。

所以,我们要做的正确方法是要保持它在缓存:

var buffers = []; 
readstream.on("data", function (chunk) { 
    buffers.push(chunk) 
}); 


readstream.on("end", function() { 
    res.set("Content-Disposition","attachment; filename=" + fileName); 
    res.send(Buffer.concat(buffers)); 
}); 
+0

感谢您的解释......您的解决方案非常棒。 – user3658423