Многократное хранение памяти в @ google-cloud / хранилище не завершено - PullRequest
0 голосов
/ 26 мая 2020

У меня есть маршрут Express, который подключается к моей корзине хранилища Google и загружает изображение. Я пытался придерживаться примеров кода Google, но go из буфера multer прямо в корзину.

Процесс, похоже, завершился без возврата en err. Однако файл появляется в корзине с размером 0Б. Кажется, метаданные приходят, а буфер изображений - нет ... ??

Кто-нибудь может увидеть, что я делаю неправильно?

Если возможно, я бы хотел получить это для работы без помощи дополнительных NPM пакетов помощи, таких как multer-cloud-storage и всех других вариантов.

enter image description here

const Multer = require("multer");
const multer = Multer({
    storage: Multer.MemoryStorage,
    fileSize: 5 * 1024 * 1024
  });
const {Storage} = require('@google-cloud/storage');
const storage = new Storage({
    projectId: 'project-name',
    keyFile: '../config/project-name.json'
    });

const bucket = storage.bucket('bucket-name');

app.post('/upload', multer.single('file'), function (req, res) {    

    const blob = bucket.file(req.file.originalname);
    const blobStream = blob.createWriteStream({
        metadata: {
            contentType: req.file.mimetype
        },
        resumable: false
    });
    blobStream.on('error', err => {
        next(err);
        console.log(err);
        return;
    });
    blobStream.on('finish', () => {
        blob.makePublic().then(() => {
            res.status(200).send(`Success!`);
        })
    })
    blobStream.end();
})

Ответы [ 2 ]

0 голосов
/ 24 июня 2020

Вы определяете и открываете поток, но ничего в него не записываете.

Если вам не нужны небольшие накладные расходы на многооблачное хранилище, я бы посоветовал взглянуть на src / index.ts файл. Функция _handleFile обрабатывает все задачи записи. Волшебство c происходит на

file.stream.pipe(blobStream)
  .on('error', (err) => cb(err))
  .on('finish', (file) => {
    const name = blob.metadata.name;
    const filename = name.substr(name.lastIndexOf('/')+1);
    cb(null, {
        bucket: blob.metadata.bucket,
        destination: this.blobFile.destination,
        filename,
        path: `${this.blobFile.destination}${filename}`,
        contentType: blob.metadata.contentType,
        size: blob.metadata.size,
        uri: `gs://${blob.metadata.bucket}/${this.blobFile.destination}${filename}`,
        linkUrl: `https://storage.cloud.google.com/${blob.metadata.bucket}/${this.blobFile.destination}${filename}`,
        selfLink: blob.metadata.selfLink,
                        })
});
0 голосов
/ 27 мая 2020

Собственный поток узла у меня не работал. Итак, streamifier это так.

Маршрут Express, который передает загруженное изображение из Multer MemoryStorage в корзину GCS, минуя сохранение на диске.

Учитывая, что это рекомендованный шаблон Google, я был разочарован неполнотой их примеров кода и слабыми ответами здесь, на SO.

    // npm streamifier
    const streamifier = require('streamifier');
    // npm multer
    const Multer = require("multer");
    const multer = Multer({
        storage: Multer.MemoryStorage,
        fileSize: 5 * 1024 * 1024
      });
    // Google Cloud Storage GCS
    const {Storage} = require('@google-cloud/storage');
    const storage = new Storage({
        projectId: 'my-project',
        keyFile: 'my-project.json'
        });
    const bucket = storage.bucket('my-bucket');

    // Express Route Hendler
    app.post('/upload', multer.single('file'), function (req, res) {
        // grab original file name out of multer obj
        const blob = bucket.file(req.file.originalname);
        // create the GCS stream handler
        const blobStream = blob.createWriteStream()
        // Yuck...
        return new Promise((resolve, reject) => {
                streamifier.createReadStream(req.file.buffer)
                    .on('error', (err) => {
                        return reject(err);
                    })
                    .pipe(blobStream)
                    .on('finish', (resp) => {
                       res.send('done') 
                    });
            })
    }); //end route
...