大家好,我花了将近一天的时间试图弄明白这个。我正在使用multer的inMemory标志从我的网页上传图像。显而易见的尝试是将从multer接收的缓冲区写入GridFs(更具体地说是GridStore)。
这是我的闷热代码
product.js(路线/控制器)
var DB = rek('database');
var router = express.Router();
var multer = require("multer");
var uploadOptions = {inMemory:true, onFileUploadComplete: uploadDone}
router.post('/product/:productId/images/', multer(uploadOptions), uploadImageResponse);
function uploadDone(file) {
var options = {
name:file.name,
mode:"w+",
content_type:file.mimetype,
w: "majority",
chunkSize: 1024,
metadata:file
};
var GridStore = new DB.GridStore(DB.connection, file.name, "w+", options);
GridStore.open(function(err, GS){
if(err) throw err;
return GS.write(file.buffer, function(err, GS){
console.log("file written");
if(err) throw err;
return GS.close(function(err, result){
if(err) throw err
console.log(result);
})
})
});
}
我的DB对象来自哪里?我只是在初始化期间将它添加到猫鼬对象中。这就是代码的样子
database.js
var mongoose = require("mongoose"),
mongooseTimestamps = require("mongoose-concrete-timestamps"),
autoIncrement = require("mongoose-auto-increment"),
config = require("../config"),
Grid = require("gridfs-stream");
mongoose.connect( config.database['development'].url + "" + config.database['development'].name );
var db = mongoose.connection;
db.once("open", function(err){
if(err) throw err
mongoose.GridStore = mongoose.mongo.GridStore
})
db.on("error",function(errMsg){
console.log("Error Connecting to Mongo: " + errMsg);
});
mongoose.set('debug', true);
mongoose.plugin(mongooseTimestamps);
autoIncrement.initialize(db);
module.exports = mongoose;
因此,在更改我的代码无数次并达到相同结果后,这是我自己的目标 - 没有写入,没有错误
我每次都会从mongoose输出日志中得到这个
POST /product/1000/images 200 4.494 ms - 22
Mongoose: fs.chunks.ensureIndex([ [ 'files_id', 1 ], [ 'n', 1 ] ]) { w: 'majority' }
Mongoose: fs.files.find({ filename: '2b08f506ed277eda45f9fc400c098aa1.jpg' }) { readPreference: 'primary', w: 'majority' }
Mongoose: fs.chunks.find({ n: 0, files_id: ObjectId("54bb87aaabf2c0416a50c068") }) { readPreference: 'primary', w: 'majority' }
如果我错了,请纠正我,但为什么我在“插入/写入”GridFS时会进行查找。到目前为止,我得到了这个输出,我的断点只能让我得到GridStore.open的调用,我正确地恢复了流,但是写入永远不会发生,并且不会抛出任何错误。
到目前为止我尝试了什么
非常感谢任何帮助。
答案 0 :(得分:3)
现在,你在这里错过的是“inMemory”选项中的“缓冲区”不是“或/或”,并不代表内容被“保留在内存中”。它实际上是数据的“副本”,也发送到磁盘上的临时文件。
因此,如果你设置“inMemory”并不重要,因为仍然会创建文件(默认情况下在/tmp
目录中),但这些当然会在超出范围时取消链接:
var async = require('async'),
express = require('express'),
multer = require('multer'),
fs = require('fs'),
mongoose = require('mongoose'),
Grid = require('gridfs-stream'),
Schema = mongoose.Schema;
Grid.mongo = mongoose.mongo;
var app = express(),
gfs = {};
// Set up multer middleware
app.use(
multer({
//inMemory: true
})
);
// Register handler
app.post('/',function (req,res) {
async.eachLimit(Object.keys(req.files), 10, function(file,callback) {
var fileobj = req.files[file];
var writeStream = gfs.createWriteStream({
"filename": fileobj.fieldname
});
fs.createReadStream(fileobj.path).pipe(writeStream);
writeStream.on('close',function() {
console.log('done');
callback();
});
writeStream.on('error',callback);
},function(err) {
if (err) {
console.log(err);
res.status(500).end();
}
res.status(200).end();
});
});
mongoose.connect('mongodb://localhost/test');
// Start app listen and events
var server = app.listen(3000,function() {
mongoose.connection.on('open',function(err) {
if (err) throw err;
// Set up connection
gfs = Grid(mongoose.connection.db);
console.log('listening and connected');
});
});
当然是一个简单的测试:
var FormData = require('form-data'),
fs = require('fs'),
http = require('http');
var fname = 'GearsLogo.png';
var form = new FormData();
form.append(fname,fs.createReadStream(fname))
var request = http.request({
method: 'post',
port: 3000,
headers: form.getHeaders()
});
form.pipe(request);
request.on('response',function(res) {
console.log(res.statusCode);
});
或者使用您的请求方法调用中间件,和/或设置onFileUploadComplete()
处理程序,而不是迭代req.files
的内容。 “gridfs = stream”包可能是你必须上传内容的最简单的选项,并且尝试从一个副本工作,这个副本实际上不会提供任何真正的优势,因为IO成本和存储总是存在。