使用 Google Cloud Functions Node JS 10 仅从特定存储桶目录复制事件驱动的文件
Posted
技术标签:
【中文标题】使用 Google Cloud Functions Node JS 10 仅从特定存储桶目录复制事件驱动的文件【英文标题】:Event driven file copy from only specific bucket directory with Google Cloud Functions Node JS 10 【发布时间】:2020-03-08 00:23:43 【问题描述】:我得到了一个事件驱动的 Google Cloud Function (Node JS 10) 的帮助,可以将文件复制到另一个 Google Cloud Storage 存储桶中,并希望能更进一步。
我需要过滤这些触发器文件以仅从一个文件夹及其子目录复制文件,而不是整个存储桶中的任何文件。
所以为免生疑问,如果我有:
bucket-a/folder-1/folder-a/folder-x
bucket-a/folder-2/folder-b/folder-y
bucket-a/folder-3/folder-c/folder-z
我想复制所有登陆 bucket-a/folder-2/folder-b 及其所有子目录的文件。
但不要复制位于文件夹 1、文件夹 3 或其任何子目录中的任何文件。
只是不确定在何处或如何将“if”参数引入已经运行良好的内容。
这是目前为止的代码:
const Storage = require('@google-cloud/storage');
const path = require('path');
exports.helloGCS = (event, context) =>
const storage = new Storage();
const gcsEvent = event;
const sourceFileBucket = gcsEvent.bucket
const sourcePathOnly = gcsEvent.name
const sourceFolder = sourcePathOnly.split('/').slice(-2)
const destFileBucket = 'my_dest_bucket'
storage
.bucket(sourceFileBucket)
.file(sourcePathOnly)
.copy(storage.bucket(destFileBucket).file(sourceFolder[0] + '/' + sourceFolder[1]));
;
任何帮助将不胜感激。
这是给我 sourcePathOnly 未定义错误的当前代码,并且还在根目录下创建了两个文件夹,folder-2 和 folder-b:
const Storage = require('@google-cloud/storage');
const path = require('path');
exports.helloGCS = (event, context) =>
const gcsEvent = event;
const storage = new Storage()
// Process only if it's in the correct folder
if (sourcePathOnly.indexOf('folder-2/folder-b') > -1)
const sourcePathOnly = gcsEvent.name
const sourceFileBucket = gcsEvent.bucket
const sourceFolder = sourcePathOnly.split('/').slice(-2)
const destFileBucket = 'my_dest_bucket'
storage
.bucket(sourceFileBucket)
.file(sourcePathOnly)
.copy(storage.bucket(destFileBucket).file(sourceFolder[0] + '/' +
sourceFolder[1]));
【问题讨论】:
【参考方案1】:Cloud Storage 和 Cloud Storage 上的事件功能非常强大。但是,您无法设置触发事件的条件。
顺便说一句,你必须在你的代码中设置一个“手动过滤器”
exports.helloGCS = (event, context) =>
const gcsEvent = event;
const sourcePathOnly = gcsEvent.name
// Process only if it's in the correct folder
if (sourcePathOnly.indexOf('folder-2/folder-b') > -1)
const storage = new Storage();
const sourceFileBucket = gcsEvent.bucket
const sourceFolder = sourcePathOnly.split('/').slice(-2)
const destFileBucket = 'my_dest_bucket'
storage
.bucket(sourceFileBucket)
.file(sourcePathOnly)
.copy(storage.bucket(destFileBucket).file(sourceFolder[0] + '/' +
sourceFolder[1]));
现在您只处理来自您想要的 src 路径的文件。
不好的是,您的函数将在存储桶中创建的每个文件上触发,因此您的函数将启动、执行检查并退出。您将因为什么都不做而收取 100 毫秒的处理费用。 我已经提出了关于这个主题的功能请求。
【讨论】:
非常感谢纪尧姆。不幸的是,收到“错误:函数执行失败。详细信息:无法读取未定义的属性“拆分””消息。 希望他们实现您的功能要求。与此同时,希望它不应该是大量文件。 ...我查看了调用云函数的成本...似乎是每百万次调用大约 0.40 美元。每美元大约有 250 万个新文件。 是的,限制很高,每个项目每月有 2M 免费。但我不知道您旁边的其他调用,但这会增加每月项目的调用次数和 CPU/内存消耗,并且您会很快达到计费限制(高于免费套餐) 关于代码,我不明白为什么拆分会有问题。我没有更改这部分,我只是添加了一个 if 并使用复制粘贴移动了一些行。您是否仔细检查了您的代码?【参考方案2】:存储桶的工作方式与文件系统不完全相同,您可以在link 上查看 Google Cloud Storage 结构和层次结构信息。
为了能够过滤您指定的需要,我建议您列出存储桶中的所有对象,然后从您想要的文件夹中过滤您需要的对象。
当您将某些内容存储在存储桶中时,格式将是这样的:
gsutil 将使用 delimiter="/" 和 prefix="abc" 为指定存储桶发出存储桶列表请求。然后会检查bucket列表结果,判断bucket中是否有路径以gs://your-bucket/abc/开头的对象,判断是把target当作对象名还是目录名。反过来,这会影响您创建的对象的名称:如果上述检查表明存在“abc”目录,您最终将得到对象 gs://your-bucket/abc/your-file;否则你会得到对象 gs://your-bucket/abc。
希望这对您有所帮助。告诉我。
【讨论】:
感谢 Stefan 的链接。以上是关于使用 Google Cloud Functions Node JS 10 仅从特定存储桶目录复制事件驱动的文件的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Google Cloud SDK 列出所有 Cloud Functions?
使用 Cloud Functions for Firebase 和 @google-cloud/storage 删除图像时出现问题
使用 Google Cloud Functions 的微服务 API 网关