Google cloud platform 如何获取“a”的更新时间;目录";使用GCS Java API的blob?

Google cloud platform 如何获取“a”的更新时间;目录";使用GCS Java API的blob?,google-cloud-platform,google-cloud-storage,Google Cloud Platform,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: ST

我在谷歌云存储桶中创建了一个“目录”。我可以使用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中显示为null。以下是相关代码:

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
为false,并且存在非null
updateTime
s和非null
createTime
s。如何获取目录对象的
updateTime

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

你可以试试!!将文件放入bucket
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,名称为空“”。这只是谷歌发现的一个创建目录的黑客行为:创建一个空的、不可见的文件(没有名字)

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


回到你的问题上来。现在您知道目录不存在,请尝试打印名称、生成并查看发生了什么。看到isDirectory变为真是“吓人”。如果Google云存储库作为目录对象返回的是0字节的文件,那就大错特错了

此外,因为我已经在存储上让你大吃一惊了,所以我可以继续说:你不能更新云存储中的对象。仅创建、删除、读取。不许动,不许重命名!(是的,也可以在UI上执行操作,甚至是一些库…)。最后两个操作使用新路径(路径=名称,因此不移动,这是一个完整的新路径=新对象)复制blob,然后删除前一个。当您更改存储类别时也是一样的

所有这些都表明更新时间也是一个错误

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

因此,请小心使用您现在知道的Java库

如中所示,类
Blob
有一个名为
BlobInfo
的父类,子类继承了一个名为的方法。如上所述:

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

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

正如@Guillaume所提到的,在存储桶中,您并没有真正“更新”文件,因为(而是对象元数据)。在引擎盖下,无论何时“更新”对象,对象都会被删除并替换为新对象

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


更新

出现null的根本原因是由于
Storage.BlobListOption.currentDirectory()
。根据文件:

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

解决方案是删除存储.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()));

谢谢你的解释。不幸的是,getCreateTime()也返回null。我更新了我的问题,这样说。奇怪的是,对于“普通文件”,createTimes和updateTimes是存在的并且是相同的。对于目录(实际上只是空文件),它们在Java中为空,但在gsutil结果中填充且相同。@kc2001我已经更新了我的答案,请检查并让我知道这是否是您需要在我的帖子中添加解释的内容,二者最初是相同的,但如果更新或配置对象上的元数据,则更新时间将发生变化。要亲自查看,请运行此命令在对象上设置自定义元数据:
gsutil setmeta-h“x-goog-meta-dogbride:doge”gs://mybucket/Dir2/
,感谢您的解释。我尝试使用createTime而不是updateTime,但得到了相同的空结果。(我已经更新了这个问题来说明这一点。)因为“目录”实际上只是文件,所以我很惊讶地体验到与时代不同的行为。