Javascript 使用Skipper with Sails.js v0.10上载文件-如何检索新文件名
我正在升级到Javascript 使用Skipper with Sails.js v0.10上载文件-如何检索新文件名,javascript,file-upload,sails.js,multifile-uploader,skipper,Javascript,File Upload,Sails.js,Multifile Uploader,Skipper,我正在升级到Sails.js0.10版,现在需要使用来管理文件上载 当我上传一个文件时,我会使用UUID为它生成一个新名称,并将其保存在public/files/文件夹中(这会在我完成所有工作后发生变化,但现在可以进行测试) 我将原始名称和上传的名称+路径保存到Mongo数据库中 在sailsv0.9.x下,这一切都非常简单,但是使用Skipper我不知道如何读取新的文件名和路径。(显然,如果我能读懂这个名字,我就可以构建路径,尽管它实际上只是我需要的名字) 我的控制器看起来像这样 var uu
Sails.js
0.10版,现在需要使用来管理文件上载
当我上传一个文件时,我会使用UUID为它生成一个新名称,并将其保存在public/files/文件夹中(这会在我完成所有工作后发生变化,但现在可以进行测试)
我将原始名称和上传的名称+路径保存到Mongo数据库中
在sailsv0.9.x
下,这一切都非常简单,但是使用Skipper
我不知道如何读取新的文件名和路径。(显然,如果我能读懂这个名字,我就可以构建路径,尽管它实际上只是我需要的名字)
我的控制器看起来像这样
var uuid = require('node-uuid'),
path = require('path'),
blobAdapter = require('skipper-disk');
module.exports = {
upload: function(req, res) {
var receiver = blobAdapter().receive({
dirname: sails.config.appPath + "/public/files/",
saveAs: function(file) {
var filename = file.filename,
newName = uuid.v4() + path.extname(filename);
return newName;
}
}),
results = [];
req.file('docs').upload(receiver, function (err, files) {
if (err) return res.serverError(err);
async.forEach(files, function(file, next) {
Document.create({
name: file.filename,
size: file.size,
localName: // ***** how do I get the `saveAs()` value from the uploaded file *****,
path: // *** and likewise how do i get the path ******
}).exec(function(err, savedFile){
if (err) {
next(err);
} else {
results.push({
id: savedFile.id,
url: '/files/' + savedFile.localName
});
next();
}
});
}, function(err){
if (err) {
sails.log.error('caught error', err);
return res.serverError({error: err});
} else {
return res.json({ files: results });
}
});
});
},
_config: {}
};
我如何做到这一点?我现在已经解决了这个问题,我想我会分享我的解决方案,让其他在类似问题上挣扎的人受益 解决方案是根本不使用
跳过器磁盘
,而是编写自己的自定义接收器
。我创建了一个Sails服务
对象
所以在文件api/services/Uploader.js中
// Uploader utilities and helper methods
// designed to be relatively generic.
var fs = require('fs'),
Writable = require('stream').Writable;
exports.documentReceiverStream = function(options) {
var defaults = {
dirname: '/dev/null',
saveAs: function(file){
return file.filename;
},
completed: function(file, done){
done();
}
};
// I don't have access to jQuery here so this is the simplest way I
// could think of to merge the options.
opts = defaults;
if (options.dirname) opts.dirname = options.dirname;
if (options.saveAs) opts.saveAs = options.saveAs;
if (options.completed) opts.completed = options.completed;
var documentReceiver = Writable({objectMode: true});
// This `_write` method is invoked each time a new file is received
// from the Readable stream (Upstream) which is pumping filestreams
// into this receiver. (filename === `file.filename`).
documentReceiver._write = function onFile(file, encoding, done) {
var newFilename = opts.saveAs(file),
fileSavePath = opts.dirname + newFilename,
outputs = fs.createWriteStream(fileSavePath, encoding);
file.pipe(outputs);
// Garbage-collect the bytes that were already written for this file.
// (called when a read or write error occurs)
function gc(err) {
sails.log.debug("Garbage collecting file '" + file.filename + "' located at '" + fileSavePath + "'");
fs.unlink(fileSavePath, function (gcErr) {
if (gcErr) {
return done([err].concat([gcErr]));
} else {
return done(err);
}
});
};
file.on('error', function (err) {
sails.log.error('READ error on file ' + file.filename, '::', err);
});
outputs.on('error', function failedToWriteFile (err) {
sails.log.error('failed to write file', file.filename, 'with encoding', encoding, ': done =', done);
gc(err);
});
outputs.on('finish', function successfullyWroteFile () {
sails.log.debug("file uploaded")
opts.completed({
name: file.filename,
size: file.size,
localName: newFilename,
path: fileSavePath
}, done);
});
};
return documentReceiver;
}
然后我的controller
就变成了(在api/controllers/DocumentController.js
中)
我相信它可以进一步改进,但这对我来说非常有效。上载的文件对象包含您需要的所有数据:
req.file('fileTest').upload({
// You can apply a file upload limit (in bytes)
maxBytes: maxUpload,
adapter: require('skipper-disk')
}, function whenDone(err, uploadedFiles) {
if (err) {
var error = { "status": 500, "error" : err };
res.status(500);
return res.json(error);
} else {
for (var u in uploadedFiles) {
//"fd" contains the actual file path (and name) of your file on disk
fileOnDisk = uploadedFiles[u].fd;
// I suggest you stringify the object to see what it contains and might be useful to you
console.log(JSON.stringify(uploadedFiles[u]));
}
}
});
req.file('fileTest').upload({
// You can apply a file upload limit (in bytes)
maxBytes: maxUpload,
adapter: require('skipper-disk')
}, function whenDone(err, uploadedFiles) {
if (err) {
var error = { "status": 500, "error" : err };
res.status(500);
return res.json(error);
} else {
for (var u in uploadedFiles) {
//"fd" contains the actual file path (and name) of your file on disk
fileOnDisk = uploadedFiles[u].fd;
// I suggest you stringify the object to see what it contains and might be useful to you
console.log(JSON.stringify(uploadedFiles[u]));
}
}
});