3

框架: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/');
                });
            });

下载很简单:使用g​​ridfs-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。存在不匹配。文本文件不会发生这种情况。当然它与数据类型有关。

有人可以帮忙吗?

4

2 回答 2

3

将 gfs 读取流直接通过管道传输到响应。这对我有用

res.set("Content-Disposition","attachment; filename=" + fileName);
var readstream = gfs.createReadStream({_id: attachmentid});
readstream.pipe(res);
于 2015-07-02T07:07:58.790 回答
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));
});
于 2015-07-02T09:15:27.430 回答