Как получить буфер для файла (изображения) из CollectionFS

Я пытаюсь вставить изображение в PDF-файл. Я создаю серверную часть с помощью PDFkit. Я использую cfs:dropbox для хранения своих файлов. Раньше, когда я использовал cvs:filesystem, было легко добавлять изображения в мой PDF-файл, потому что они были прямо там. Теперь, когда они хранятся удаленно, я не знаю, как их добавить, поскольку PDFkit не поддерживает добавление изображений только с URL-адресом. Однако он примет буфер. Как я могу получить буфер из моих файлов CollectionFS?

Пока у меня что-то вроде этого:

var portrait = Portraits.findOne('vS2yFy4gxXdjTtz5d');
readStream = portrait.createReadStream('portraits');

Я пытался получить буфер двумя способами:

Сначала использовал dataMan, но последняя команда так и не возвращается:

var dataMan = new DataMan.ReadStream(readStream, portrait.type());
var buffer = Meteor.wrapAsync(Function.prototype.bind(dataMan.getBuffer, dataMan))();

Вторая буферизация потока вручную:

var buffer = new Buffer(0);
readStream.on('readable', function() {
    buffer = Buffer.concat([buffer, readStream.read()]);
});
readStream.on('end', function() {
    console.log(buffer.toString('base64'));
});

Кажется, это тоже никогда не вернется. Я перепроверил свой документ, чтобы убедиться, что он там и имеет действительный URL-адрес, и изображение появляется, когда я помещаю URL-адрес в свой браузер. Я что-то упускаю?


person Jared Martin    schedule 23.06.2015    source источник
comment
что значит никогда не вернется? Как/где в вашем коде вы используете эти решения. Второй должен работать.   -  person Christian Fritz    schedule 04.07.2015
comment
кроме того, вы звоните readStream.read() куда-нибудь?   -  person Christian Fritz    schedule 04.07.2015
comment
Никогда не возвращается, я имею в виду, что обратный вызов для события «конец» никогда не выполняется (я не вижу сообщения журнала в консоли).   -  person Jared Martin    schedule 07.07.2015
comment
Во второй попытке я вызвал readStream.read() в конце третьей строки.   -  person Jared Martin    schedule 07.07.2015
comment
github.com/CollectionFS/Meteor-CollectionFS/issues/457 Посмотрите пример Icellan пишет ближе к концу ветки. Примечание. Обязательно замените readable на data в обработчике событий.   -  person Brian Shamblen    schedule 08.07.2015
comment
Брайан, твой ответ кажется правильным. К сожалению, у меня не будет возможности попробовать его, пока не закончится награда. Почему бы вам не добавить это в качестве ответа, чтобы получить часть награды? Обязательно скопируйте ответ сюда, а не просто ссылку на него. В противном случае моды будут жаловаться. Позже, когда я проверю это, я отмечу это как правильное.   -  person Jared Martin    schedule 11.07.2015


Ответы (1)


Мне пришлось сделать что-то подобное, и, поскольку на этот вопрос нет ответа, вот как я это делаю:

// take a cfs file and return a base64 string
var getBase64Data = function(file, callback) {
  // callback has the form function (err, res) {}
  var readStream = file.createReadStream();
  var buffer = [];
  readStream.on('data', function(chunk) {
    buffer.push(chunk);
  });
  readStream.on('error', function(err) {
    callback(err, null);
  });
  readStream.on('end', function() {
    callback(null, buffer.concat()[0].toString('base64'));
  });
};

// wrap it to make it sync    
var getBase64DataSync = Meteor.wrapAsync(getBase64Data);

// get a cfs file
var file = Files.findOne();

// get the base64 string
var base64str = getBase64DataSync(file);

// get the buffer from the string
var buffer = new Buffer(base64str, 'base64')

Надеюсь, это поможет!

person acemtp    schedule 28.09.2015
comment
Я не проверял это, но это похоже на то, что я пытался понять. Еще в июле я просто сохранил строку base 64 прямо в коллекции, но это занимает больше места. Спасибо за вашу помощь. - person Jared Martin; 29.09.2015