【问题标题】:How to upload an in memory file data to google cloud storage using nodejs?如何使用nodejs将内存文件数据上传到谷歌云存储?
【发布时间】:2017-07-06 09:45:19
【问题描述】:

我正在从 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
}

【问题讨论】:

  • 你找到方法了吗?我也想对 JSON 数据做同样的事情。
  • 我已经发布了我使用的解决方案,抱歉耽搁了。

标签: node.js google-cloud-storage


【解决方案1】:

是的,可以从 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);
});

【讨论】:

  • 这是准确的答案。管道转换然后管道写入流。您也可以在此之后立即获取signedUrl。谢谢马修 R
【解决方案2】:

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

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)
  })
})

【讨论】:

  • 工作得很好.......非常感谢。注意:如果在上传 csv 文件时出现任何问题,您应该检查您的 contentType 元数据。因为我面临这个问题,所以我在这里说。再次非常感谢
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    您也可以上传多个文件:

    @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)
                })
            })
        }
    

    【讨论】:

      猜你喜欢
      • 2018-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-01
      • 2014-08-03
      • 1970-01-01
      • 1970-01-01
      • 2015-02-28
      相关资源
      最近更新 更多