【问题标题】:How do I read the contents of a new cloud storage file of type .json from within a cloud function?如何从云函数中读取 .json 类型的新云存储文件的内容?
【发布时间】:2017-08-18 06:25:47
【问题描述】:

传递给我的谷歌云函数的event 只真正告诉我存储桶和文件的名称,以及文件是否被删除。是的,还有更多,但似乎并没有那么有用:

{ timestamp: '2017-03-25T07:13:40.293Z', 
eventType: 'providers/cloud.storage/eventTypes/object.change', 
resource: 'projects/_/buckets/my-echo-bucket/objects/base.json#1490426020293545', 
data: { kind: 'storage#object', 
       resourceState: 'exists', 
       id: 'my-echo-bucket/base.json/1490426020293545', 
       selfLink: 'https://www.googleapis.com/storage/v1/b/my-echo-bucket/o/base.json', 
       name: 'base.json', 
       bucket: 'my-echo-bucket', 
       generation: '1490426020293545', 
       metageneration: '1', 
       contentType: 'application/json', 
       timeCreated: '2017-03-25T07:13:40.185Z', 
       updated: '2017-03-25T07:13:40.185Z', 
       storageClass: 'STANDARD', 
       size: '548', 
       md5Hash: 'YzE3ZjUyZjlkNDU5YWZiNDg2NWI0YTEyZWZhYzQyZjY=', 
       mediaLink: 'https://www.googleapis.com/storage/v1/b/my-echo-bucket/o/base.json?generation=1490426020293545&alt=media', contentLanguage: 'en', crc32c: 'BQDL9w==' } 
}

如何获取内容,而不仅仅是上传到 gs 存储桶的新 .json 文件的元数据?

我尝试在 event.data.selfLink 上使用 npm:request(),这是存储桶中文件的 URL,但返回了授权错误:

"code": 401, "message": "Anonymous users does not have storage.objects.get access to object my-echo-bucket/base.json."

在 SO 上有一个关于读取存储桶的类似问题,但可能在不同的平台上。无论如何,它没有得到答复

How do I read the contents of a file on Google Cloud Storage using javascript `

【问题讨论】:

  • 注意:这是一个self answered question。希望其他人觉得它有用。如果你有更好/更干净/更短的答案,我会考虑的。

标签: javascript google-cloud-storage google-cloud-functions


【解决方案1】:

您需要使用客户端库进行 google 存储,而不是通过 URL 访问。仅当文件公开访问时,对 URL 使用 request() 才有效。

在包含您的项目的 npm 管理目录中导入 google 云存储库。

npm i @google-cloud/storage -S

npm page for google-cloud/storage 有不错的示例,但我必须通读一下 API 才能看到下载到内存的简单方法。

在 Google Cloud Functions 环境中,您无需向存储提供任何 api 密钥等作为初始化。

const storage = require('@google-cloud/storage')();

传递的有关文件的元数据可用于确定您是否真的需要该文件。

当您需要该文件时,可以使用 file.download 函数下载它,该函数可以接受回调,或者在缺少回调的情况下将返回一个 Promise。
然而,数据以 Buffer 的形式返回,因此您需要调用 data.toString('utf-8') 将其转换为 utf-8 编码字符串。

const storage = require('@google-cloud/storage')();

exports.logNewJSONFiles = function logNewJSONFiles(event){
    return new Promise(function(resolve, reject){
        const file = event.data;
        if (!file){
            console.log("not a file event");
            return resolve();
        }
        if (file.resourceState === 'not_exists'){
            console.log("file deletion event");
            return resolve();
        }
        if (file.contentType !== 'application/json'){
            console.log("not a json file");
            return resolve();
        }
        if (!file.bucket){
            console.log("bucket not provided");
            return resolve();
        }
        if (!file.name){
            console.log("file name not provided");
            return resolve();
        }
        (storage
         .bucket(file.bucket)
         .file(file.name)
         .download()
         .then(function(data){
             if (data)
                 return data.toString('utf-8');
         })
         .then(function(data){
             if (data) {
                 console.log("new file "+file.name);
                 console.log(data);
                 resolve(data);
             }
         })
         .catch(function(e){ reject(e); })
             );
    });
};

按预期部署:

gcloud beta functions deploy logNewJSONFiles --stage-bucket gs://my-stage-bucket --trigger-bucket gs://my-echo-bucket

记得在 Google Cloud Platform 上的 Stackdriver:Logging 页面中查看 console.log 条目。

更新:(2019 年)云功能首次发布时,ECONNRESET 存在一些问题。我认为现在已经解决了。如果没有,请使用 npm:promise-retry

【讨论】:

  • +1 修复 ECONNRESET 错误。我必须强制我的 cron 函数每天重试几次,以确保它能够正确写入所有文件。
【解决方案2】:
npm install @google-cloud/storage --production

package.json:

{
  "main": "app.js",
  "dependencies": {
    "@google-cloud/storage": "^1.2.1"
  }
}

您应该实现npm ls 不会显示像npm ERR! missing: 这样的错误。

app.js:

...

  const storage = require("@google-cloud/storage")();
  storage.
    bucket("mybucket").
    file("myfile.txt").
    download( function(err, contents) {
      console.log(contents.toString());
    } );

【讨论】:

    猜你喜欢
    • 2020-10-14
    • 2018-08-18
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    相关资源
    最近更新 更多