2015-07-02 145 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