框架:node.js / express.js / busboy / gridfs-stream(mongodb)
我正在使用busboy上传文件,然后使用gridfs-stream在mongodb gridfs中存储文件。
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-stream的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。有一个不匹配。文本文件不会发生这种情况。当然它与数据类型有关。
有人可以帮忙吗?
答案 0 :(得分:3)
将gfs读取流直接传递给响应。这对我有用
res.set("Content-Disposition","attachment; filename=" + fileName);
var readstream = gfs.createReadStream({_id: attachmentid});
readstream.pipe(res);
答案 1 :(得分:1)
就像Sasikanth说你可以用管道来解决这个问题,这是最好的方法。
但是如果您想知道当前方法有什么问题,那么我建议您阅读Buffer文档。您将变量命名为buffer
但是指定了字符串。
然后在您的data
回调中,您正在使用Buffer添加字符串。执行此操作时,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));
});