我真的在连接busboy和流写作方面苦苦挣扎。问题是我想做一些文件验证,但是我不能在不处理数据的情况下做到这一点,而且我在处理它时似乎必须将它写入文件。
当数据进入并遇到文件大小或文件类型限制等错误时,我拒绝了请求,但文件的一部分已写入磁盘。我真的想省略写作直到最后或者可能将它放入内存缓冲区。
此代码将拒绝无效的文件类型和大小限制,但它始终首先创建写入流并将文件传输到其中。我真正想做的就是移动" file.pipe(fstream);"进入file.on(' end',...回调,但当然不起作用,因为它必须在进入时编写。所以看起来我需要先将它写入分段缓冲区,然后在最后将它刷新到一个真实的文件。或者我可以写一个临时文件,并在错误删除该文件,但这似乎更加hacky和脆弱。这个看似常见的问题的最佳做法是什么?
saveFiles: function(request, options) {
return new Promise(function(resolve, reject) {
var fstream;
var totalData = 0;
request.pipe(request.busboy);
var fileIds = [];
var assets = {'assets': {}};
request.busboy.on('file', function(fieldname, file, originalName, encoding, contype) {
file.on('limit', function() {
var limitBytes = request.busboy.opts.limits.fileSize;
var limitMB = Math.round((limitBytes / 1048576) * 100) / 100;
return reject({errorMsg: 'Files exceeded the size limit of ' + limitMB + 'MB'});
});
file.on('data', function(data) {
if (totalData === 0) {
var type = fileType(data);
if(type) {
if (request.busboy.opts.limits.validFileTypes.indexOf(type.ext) === -1) {
return reject({errorMsg: 'Invalid file type "' + type.ext + '"'});
}
}
else {
return reject({errorMsg: 'Invalid file type'});
}
}
totalData += data.length;
});
var fileId = uuid.v1(); // used for file name on server
var parts = originalName.split('.');
var extension = parts[parts.length - 1].toLowerCase();
var fileName = fileId + '.' + extension;
fstream = fs.createWriteStream(__assets + fileName);
file.pipe(fstream);
file.on('end', function() {
assets['assets'][fileId] = {
fileName: fileId + '.' + extension,
originalName: originalName
};
});
});
request.busboy.on('finish', function(){
resolve(assets);
});
});
}