当前位置: 首页 > 知识库问答 >
问题:

如何使用nodejs将内存中的文件数据上传到google云存储?

归建安
2023-03-14

我从一个网址读取图像并处理它。我需要将这些数据上传到云存储中的一个文件中,目前我正在将这些数据写入一个文件,并上传该文件,然后删除该文件。有没有办法把数据直接上传到云端仓库?

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
}

共有3个答案

丁曦
2023-03-14

这个线程是旧的,但是在当前的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

刁浩言
2023-03-14

通过使用节点流,可以在不写入文件的情况下上载数据。

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)
  })
})
东方河
2023-03-14

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

这是建立在Akash的答案的基础上的,有一个对我有效的整个函数,包括图像处理步骤。

  • 使用axios从远程url检索图像流。
  • 使用夏普对图像进行更改
  • 使用Google云存储库创建文件,并将图像数据保存到Google云存储中的文件中。(更多节点文档)

如果您是使用firebase存储的firebase用户,则必须仍然使用此库。用于存储的firebase web实现在节点中不工作。如果您在firebase中创建了存储,您仍然可以通过Google云存储控制台访问这些内容。它们是一样的。

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);
});
 类似资料: