问题描述
我升级到 Sails.js
0.10版,现在需要使用来管理我的文件上传。
当我上传一个文件时,我使用一个UUID为它生成一个新的名字,并保存在公共/文件/文件夹(这将改变,当我有这个所有的工作,但现在测试很好)
我保存原来的名称,上传的名称+ $路径到Mongo数据库。
这在 Sails v0.9.x
下都很简单,但是使用 Skipper
我不知道如何读取新的文件名和路径。 (显然,如果我可以读取名称,我可以构建路径,所以它只是我需要的名称)
我的控制器看起来像这样
var uuid = require('node-uuid'),
path = require('path'),
blobAdapter = require 船长盘);
module.exports = {
上传:function(req,res){
var receiver = blobAdapter()。receive({
dirname:sails.config.appPath +/ public / files /,
saveAs:function(file){
var filename = file.filename,$ b $ newName = uuid.v4( )+ path.extname(filename);
return newName;
}
}),
results = [];
$ b $ req.file('docs')。upload(receiver,function(err,files){$ b $ if if(err)return res.serverError(err);
async。 forEach(file,function(file,next){
Document.create({
name:file.filename,
size:file.size,
localName:// ** ***如何从上传的文件中获得`saveAs()`值,
path:// ***,同样如何获取路径******
})。exec(function(err,savedFile){
if(err){
next(err);
} else {
results.push({
id:savedFile.id,
url:'/ files /'+ savedFile.localName
});
next();
}
}) ;
},函数(err){
if(err){
sails.log.error('caught error',err);
return res.serverError({error :err});
} else {
return res.json({ files:results});
}
});
});
},
_config:{}
};
我该如何做?
现在我已经解决了这个问题,并认为我会分享我的解决方案,为其他人解决类似问题而努力。
解决方法是根本不使用 skipper-disk
,而是编写我自己定制的 receiver
。我已经创建了一个 Sails Service
对象。
api /服务/ Uploader.js
//上传工具和辅助方法
//设计相对通用。
var fs = require('fs'),
Writable = require('stream')。
exports.documentReceiverStream = function(options){
var defaults = {
dirname:'/ dev / null',
saveAs:function(file){
返回file.filename;
},
完成:function(file,done){
done();
}
};
//我没有在这里访问jQuery,所以这是我
//可以想到的合并选项的最简单的方法。
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});
//每当接收到一个新的文件
//时,就调用这个`_write`方法,从可读流(Upstream)中抽取文件流
//到这个接收器。 (文件名===`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);
//垃圾 - 收集已经为这个文件写入的字节。
//(发生读取或写入错误时调用)
函数gc(err){
sails.log.debug(垃圾收集文件'+ file.filename +'located在'+ fileSavePath +');
$ b fs.unlink(fileSavePath,function(gcErr){
if(gcErr){
return done([err] .concat([gcErr]));
} else {
return done(err);
}
});
};
$ b 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);
});
};
返回documentReceiver;
$ / code>
然后我的控制器
刚成为(在 api / controllers / DocumentController.js
中)
var uuid = require('node-uuid'),
path = require('path');
module.exports = {
上传:函数(req,res){
var results = [],
streamOptions = {
dirname:sails.config.appPath +/ public / files /,
saveAs:function(file){
var filename = file.filename,
newName = uuid .v4()+ path.extname(filename);
返回newName;
}
完成:function(fileData,next){
Document.create(fileData).exec(function(err,savedFile){
if(err){
next(err);
} else {
results.push({
id:savedFile.id,
url:'/ files /'+ savedFile.localName
});
next();
}
});
}
};
req.file('docs')。upload(Uploader.documentReceiverStream(streamOptions),
function(err,files){
if(err)return res.serverError err);
res.json({
message:files.length +'file(s)uploaded successfully!',
files:results
});
}
);
},
_config:{}
};
我相信它可以进一步改善,但这对我来说是完美的。
I am upgrading to Sails.js
version 0.10 and now need to use Skipper to manage my file uploads.
When I upload a file I generate a new name for it using a UUID, and save it in the public/files/ folder (this will change when I've got this all working but it's good for testing right now)
I save the original name, and the uploaded name + path into a Mongo database.
This was all quite straightforward under Sails v0.9.x
but using Skipper
I can't figure out how to read the new file name and path. (Obviously if I could read the name I could construct the path though so it's really only the name I need)
My Controller looks like this
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: {}
};
How do I do this?
I've worked this out now and thought I'd share my solution for the benefit of others struggling with similar issues.
The solution was to not use skipper-disk
at all but to write my own custom receiver
. I've created this as a Sails Service
object.
So in file 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;
}
and then my controller
just became (in api/controllers/DocumentController.js
)
var uuid = require('node-uuid'),
path = require('path');
module.exports = {
upload: function(req, res) {
var results = [],
streamOptions = {
dirname: sails.config.appPath + "/public/files/",
saveAs: function(file) {
var filename = file.filename,
newName = uuid.v4() + path.extname(filename);
return newName;
},
completed: function(fileData, next) {
Document.create(fileData).exec(function(err, savedFile){
if (err) {
next(err);
} else {
results.push({
id: savedFile.id,
url: '/files/' + savedFile.localName
});
next();
}
});
}
};
req.file('docs').upload(Uploader.documentReceiverStream(streamOptions),
function (err, files) {
if (err) return res.serverError(err);
res.json({
message: files.length + ' file(s) uploaded successfully!',
files: results
});
}
);
},
_config: {}
};
I'm sure it can be improved further but this works perfectly for me.
这篇关于使用Skipper和Sails.js v0.10上传文件 - 如何检索新的文件名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!