createWriteStream в буфер памяти и позже на диск
Я действительно борюсь с connect-busboy и потоковым письмом. Проблема в том, что я хочу выполнить некоторую проверку файла, но я не могу сделать это без предварительной обработки данных, и мне кажется, что мне нужно записать это в файл, пока я его обрабатываю.
Когда данные поступают, и я сталкиваюсь с ошибками, такими как размер файла или ограничения типов файлов, я отклоняю запрос, но часть файла уже записана на диск. Я действительно хочу пропустить запись до самого конца или, возможно, поместить ее в буфер памяти.
Этот код будет отклонять недопустимые типы файлов и ограничения размера, но он всегда сначала создает поток записи и передает в него файл. То, что я действительно хочу сделать, это переместить "file.pipe(fstream);" в файл.on('end',... обратный вызов, но это, конечно, не работает, потому что он должен быть записан, как он поступает. Так что, кажется, мне нужно сначала записать его в промежуточный буфер, а затем в конец сбросить его в реальный файл. В качестве альтернативы я мог бы записать во временный файл и при ошибке удалить этот файл, но это кажется гораздо более хакерским и хрупким. Какова наилучшая практика для этой, казалось бы, распространенной проблемы?
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);
});
});
}