如何解决如何使用 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 举报,一经查实,本站将立刻删除。