微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 GCS Java API 获取“目录”blob 的更新时间?

如何解决如何使用 GCS Java API 获取“目录”blob 的更新时间?

我在 Google Cloud Storage 存储分区中创建了一个“目录”。我可以使用 gsutil 列出它,并看到相关的时间:

>gsutil ls -L gs://mybucket/Dir2/
gs://mybucket/Dir2/:
    Creation time:          Thu,11 Feb 2021 19:15:32 GMT
    Update time:            Thu,11 Feb 2021 19:15:32 GMT
    Storage class:          STANDARD
    Content-Length:         0
    ...
TOTAL: 1 objects,0 bytes (0 B)

在我的 Java 代码中,我试图检索更新时间,但 updateTime(和 createTime)在 blob 中显示为空。相关代码如下:

blobs = bucket.list(Storage.BlobListOption.prefix(sourcePath),Storage.BlobListOption.currentDirectory());
for (Blob blob : blobs.iterateall()) {
    // ...
    Long updateTime = blob.getUpdateTime();
    Long createTime = blob.getCreateTime();
    // ==> updateTime,createTime are null,blob.isDirectory() is true
}

对于“普通文件”,isDirectory为假,有非空updateTime和非空createTime。如何获取目录对象的 updateTime

解决方法

Cloud Storage 上不存在目录。好吧好吧,很难接受,让我解释一下!存储桶是一个桶,您将所有对象放在桶的根路径中。对象名称可以包含 /,并且在 UI 上,具有相同前缀、由 / 分隔的对象组合在一起。

你可以试试!!将文件放入您的存储桶 gs://myBucket/dir/myObject.txt 您可以在 UI 上看到一个目录。删除您的对象,目录消失。它只是对象路径的一部分!

出于同样的原因,您只能按前缀搜索,而不能按后缀搜索。

那么,现在,为什么可以在 UI 上创建文件夹?只是因为一些客户要求这个!但是现在,请仔细查看您的目录。执行gsutil ls -L gs://mybucket/Dir2/

你应该看到这个

gs://mybucket/Dir2/:
    Creation time:          Thu,11 Feb 2021 22:32:36 GMT
    Update time:            Thu,11 Feb 2021 22:32:36 GMT
    Storage class:          STANDARD
    Content-Length:         0
    Content-Type:           text/plain
    Hash (crc32c):          AAAAAA==
    Hash (md5):             1B2M2Y8AsgTpgAmY7PhCfg==
    ETag:                   CIL1r8Xx4u4CEAE=
    Generation:             1613082756119170
    Metageneration:         1
    ACL:                    []
TOTAL: 1 objects,0 bytes (0 B)

什么意思?您有一个文件,大小为 0,名称为空“”。这只是谷歌发现的一个创建目录的hack:创建一个空的不可见文件(没有名字)!

删除它,目录消失,和以前一样!没有魔法!


回到你的问题。既然您知道目录不存在,请尝试打印名称、生成并查看会发生什么。看到 isDirectory 为 true 是“可怕的”。如果确实是 Google Cloud Storage 库作为目录对象返回的 0 字节文件,那就大错特错了!

此外,因为我已经让您对存储感到震惊,所以我可以继续:您无法更新 Cloud Storage 中的对象。只创建、删除、读取。不动,不改名! (是的,也可以在 UI 上进行操作,甚至是一些库...)。最后 2 个操作使用新路径(路径 = 名称,所以不要移动,它是一个全新的路径 = 新对象)复制 blob,然后删除前一个。当您更改存储类别时也是如此。

这一切说明updateTime也是错误的!!

我在 Python 中没有这个(只有创建和删除时间,没有布尔值来指示是否是目录)。

因此请注意使用您现在所知道的 Java 库!

,

正如您在 client library doc 中看到的,类 Blob 有一个名为 BlobInfo 的父类,子类继承了一个名为 getUpdateTime() 的方法。如上所述:

getUpdateTime() 返回 blob 元数据的最后修改时间,表示为自 Unix 纪元以来的毫秒数。

因此,此方法不适用于您尝试使用它的目的。它用于检查对象元数据更新的时间。

正如@Guillaume 提到的,在存储桶中,您并没有真正“更新”文件,因为 objects are immutable(而是对象元数据 varies)。在幕后,每当您“更新”对象时,对象都会被删除并替换为新对象。

因此,解决方案是使用 getCreateTime() 查看上次创建/替换对象的时间。


更新

您看到 null 的根本原因是因为 Storage.BlobListOption.currentDirectory()。根据文档:

如果指定,则以类似目录的模式返回结果。名称在可能的前缀(字符串)之后不包含“/”分隔符的 Blob 将按原样返回。名称在可能的前缀(字符串)之后包含“/”分隔符的 Blob 将在分隔符后截断其名称,并且 将作为 Blob 对象返回,其中只有 BlobInfo.getBlobId()、BlobInfo.getSize()和 BlobInfo.isDirectory() 已设置

解决方案是删除 Storage.BlobListOption.currentDirectory()。或者您可以使用此代码获取特定目录。即使目录为空,它也会工作,但 isDirectory() 将始终返回 false:

Blob blob = storage.get(bucketName,sourcePath,Storage.BlobGetOption.fields(Storage.BlobField.values()));
System.out.println("Bucket: " + blob.getBucket());
System.out.println("Name: " + blob.getName());
System.out.println("TimeCreated: " + new Date(blob.getCreateTime()));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。