繁体   English   中英

如何使用nodejs将内存文件数据上传到谷歌云存储?

[英]How to upload an in memory file data to google cloud storage using nodejs?

我正在从 url 读取图像并对其进行处理。 我需要将此数据上传到云存储中的文件,目前我正在将数据写入文件并上传此文件,然后删除此文件。 有没有办法可以将数据直接上传到云存储?

static async uploadDataToCloudStorage(rc : RunContextServer, bucket : string, path : string, data : any, mimeVal : string | false) : Promise<string> {
  if(!mimeVal) return ''

  const extension = mime.extension(mimeVal),
        filename  = await this.getFileName(rc, bucket, extension, path),
        modPath   = (path) ? (path + '/') : '',
        res       = await fs.writeFileSync(`/tmp/${filename}.${extension}`, data, 'binary'),
        fileUrl   = await this.upload(rc, bucket, 
                            `/tmp/${filename}.${extension}`,
                            `${modPath}${filename}.${extension}`)
                   
  await fs.unlinkSync(`/tmp/${filename}.${extension}`)

  return fileUrl
}

static async upload(rc : RunContextServer, bucketName: string, filePath : string, destination : string) : Promise<string> {
  const bucket : any = cloudStorage.bucket(bucketName),
        data   : any = await bucket.upload(filePath, {destination})

  return data[0].metadata.name
}

是的,可以从 URL 检索图像,对图像执行编辑,然后使用 nodejs 将其上传到 Google Cloud Storage(或 Firebase 存储),而无需在本地保存文件。

这是建立在 Akash 的答案之上的,它具有对我有用的整个功能,包括图像处理步骤。

脚步

如果您是使用 firebase 存储的firebase用户,您仍必须使用此库。 用于存储的 firebase web 实现在 node.js 中不起作用。 如果您在 firebase 中创建了存储,您仍然可以通过Google Cloud Storage Console访问这一切。 他们是一样的东西。

const axios = require('axios');
const sharp = require('sharp');
const { Storage } = require('@google-cloud/storage');

const processImage = (imageUrl) => {
    return new Promise((resolve, reject) => {

        // Your Google Cloud Platform project ID
        const projectId = '<project-id>';

        // Creates a client
        const storage = new Storage({
            projectId: projectId,
        });

        // Configure axios to receive a response type of stream, and get a readableStream of the image from the specified URL
        axios({
            method:'get',
            url: imageUrl,
            responseType:'stream'
        })
        .then((response) => {

            // Create the image manipulation function
            var transformer = sharp()
            .resize(300)
            .jpeg();

            gcFile = storage.bucket('<bucket-path>').file('my-file.jpg')

            // Pipe the axios response data through the image transformer and to Google Cloud
            response.data
            .pipe(transformer)
            .pipe(gcFile.createWriteStream({
                resumable  : false,
                validation : false,
                contentType: "auto",
                metadata   : {
                    'Cache-Control': 'public, max-age=31536000'}
            }))
            .on('error', (error) => { 
                reject(error) 
            })
            .on('finish', () => { 
                resolve(true)
            });
        })
        .catch(err => {
            reject("Image transfer error. ", err);
        });
    })
}

processImage("<url-to-image>")
.then(res => {
  console.log("Complete.", res);
})
.catch(err => {
  console.log("Error", err);
});

可以使用节点流上传数据而无需写入文件。

const stream     = require('stream'),
      dataStream = new stream.PassThrough(),
      gcFile     = cloudStorage.bucket(bucketName).file(fileName)

dataStream.push('content-to-upload')
dataStream.push(null)

await new Promise((resolve, reject) => {
  dataStream.pipe(gcFile.createWriteStream({
    resumable  : false,
    validation : false,
    metadata   : {'Cache-Control': 'public, max-age=31536000'}
  }))
  .on('error', (error : Error) => { 
    reject(error) 
  })
  .on('finish', () => { 
    resolve(true)
  })
})

该线程很旧,但在当前 API 中, File对象与 Streams 一起使用

所以你可以有这样的东西来从内存上传一个 JSON 文件:

const { Readable } = require("stream")
const { Storage } = require('@google-cloud/storage');

const bucketName = '...';
const filePath = 'test_file_from_memory.json';
const storage = new Storage({
  projectId: '...',
  keyFilename: '...'
});
(() => {
  const json = {
    prop: 'one',
    att: 2
  };
  const file = storage.bucket(bucketName).file(filePath);
  Readable.from(JSON.stringify(json))
    .pipe(file.createWriteStream({
      metadata: {
        contentType: 'text/json'
      }
    }).on('error', (error) => {
      console.log('error', error)
    }).on('finish', () => {
      console.log('done');
    }));
})();

来源: https ://googleapis.dev/nodejs/storage/latest/File.html#createWriteStream

您还可以上传多个文件:

@Post('upload')
@UseInterceptors(AnyFilesInterceptor())
uploadFile(@UploadedFiles())
    const storage = new Storage();
    for (const file of files) {
        const dataStream = new stream.PassThrough();
        const gcFile = storage.bucket('upload-lists').file(file.originalname)
        dataStream.push(file.buffer);
        dataStream.push(null);
        new Promise((resolve, reject) => {
            dataStream.pipe(gcFile.createWriteStream({
                resumable: false,
                validation: false,
                // Enable long-lived HTTP caching headers
                // Use only if the contents of the file will never change
                // (If the contents will change, use cacheControl: 'no-cache')
                metadata: { 'Cache-Control': 'public, max-age=31536000' }
            })).on('error', (error: Error) => {
                reject(error)
            }).on('finish', () => {
                resolve(true)
            })
        })
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM