如何使用 Java 检查给定 S3 存储桶中是否存在指定密钥
我想使用 Java 检查给定存储桶中是否存在密钥。我查看了 API,但没有任何有用的方法。我尝试使用 getObject 但它引发了异常。
I would like to check if a key exists in a given bucket using Java. I looked at the API but there aren't any methods that are useful. I tried to use getObject
but it threw an exception.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
现在有一个 doesObjectExist 官方Java API中的方法。
享受!
编辑:这仅适用于适用于 Java 1.x 的 AWS 开发工具包。
There's now a doesObjectExist method in the official Java API.
Enjoy!
EDIT: This works only in AWS SDK for Java 1.x.
更新:
似乎有一个新的 API 可以检查这一点。请参阅本页中的另一个答案: https://stackoverflow.com/a/36653034/435605
原始帖子:
使用
errorCode.equals("NoSuchKey")
关于异常的注意事项:我知道异常不应该用于流量控制。问题是 Amazon 没有提供任何 api 来检查此流程 - 只是有关异常的文档。
Update:
It seems there's a new API to check just that. See another answer in this page: https://stackoverflow.com/a/36653034/435605
Original post:
Use
errorCode.equals("NoSuchKey")
Note about the exception: I know exceptions should not be used for flow control. The problem is that Amazon didn't provide any api to check this flow - just documentation about the exception.
AWS SDK for Java 2.x 的更新
在 SDK V2 中执行此操作的正确方法是使用
S3Client.headObject()
。由 [4.1.1. 中的 AWS 变更日志] 正式支持。 S3 操作迁移][2] 部分。
示例代码:
有关 HeadObject 操作的更多信息可以在官方文档中找到: HeadObject。
Update for the AWS SDK for Java 2.x
The right way to do it in SDK V2, without the overload of actually getting the object, is to use
S3Client.headObject()
.Officially backed by AWS Change Log in the [4.1.1. S3 Operation Migration][2] section.
Example code:
More info about the HeadObject operation can be found in the official documentation: HeadObject.
使用 AWS 开发工具包使用 getObjectMetadata 方法。如果密钥不存在,该方法将抛出 AmazonServiceException。
Using the AWS SDK use the getObjectMetadata method. The method will throw an AmazonServiceException if the key doesn't exist.
在 Amazon Java SDK 1.10+ 中,您可以使用
getStatusCode()
获取HTTP响应的状态码,如果对象不存在则为404。getObjectMetadata()
消耗的资源更少,并且不需要像getObject()
那样关闭响应。在以前的版本中,您可以使用
getErrorCode()
并检查适当的字符串(取决于版本)。In Amazon Java SDK 1.10+, you can use
getStatusCode()
to get the status code of the HTTP response, which will be 404 if the object does not exist.getObjectMetadata()
consumes fewer resources, and the response doesn't need to be closed likegetObject()
.In previous versions, you can use
getErrorCode()
and check for the appropriate string (depends on the version).使用 ListObjectsRequest 设置 Prefix 作为密钥。
.NET代码:
Use ListObjectsRequest setting Prefix as your key.
.NET code:
对于 PHP(我知道问题是 Java,但 Google 把我带到这里),您可以使用流包装器和 file_exists
For PHP (I know the question is Java, but Google brought me here), you can use stream wrappers and file_exists
此 java 代码检查 s3 存储桶中是否存在密钥(文件)。
This java code checks if the key (file) exists in s3 bucket.
正如其他人提到的,对于 AWS S3 Java SDK 2.10+,您可以使用 HeadObjectRequest 对象来检查您的 S3 存储桶中是否有文件。这就像 GET 请求一样,但实际上并没有获取文件。
示例代码,因为其他人实际上没有在上面添加任何代码:
As others have mentioned, for the AWS S3 Java SDK 2.10+ you can use the HeadObjectRequest object to check if there is a file in your S3 bucket. This will act like a GET request without actually getting the file.
Example code since others haven't actually added any code above:
将您的路径分成桶和对象。
使用方法
doesBucketExist
测试存储桶,使用列表的大小测试对象(如果不存在则为 0)。
所以这段代码将执行以下操作:
Break your path into bucket and object.
Testing the bucket using the method
doesBucketExist
,Testing the object using the size of the listing (0 in case not exist).
So this code will do:
其他答案适用于 AWS SDK v1。以下是 AWS SDK v2(当前为 2.3.9)的方法。
请注意,v2 SDK 目前不包含
getObjectMetadata
和doesObjectExist
方法!所以这些不再是选择。我们被迫使用getObject
或listObjects
。目前,
listObjects
调用的成本是getObject
的 12.5 倍。但 AWS 还会对下载的任何数据收费,这会提高getObject
如果文件存在 的价格。只要该文件不太可能存在(例如,您随机生成了一个新的 UUID 密钥,只需仔细检查它是否未被占用),那么调用getObject
的成本要低得多我的计算。不过,为了安全起见,我添加了
range()
规范,要求 AWS 仅发送文件的几个字节。据我所知,SDK 将始终尊重这一点,并且不会向您收取下载整个文件的费用。但我还没有验证这一点,所以依赖这种行为需要您自担风险! (另外,我不确定如果 S3 对象的长度为 0 字节,range
的行为如何。)注意:此代码假设
s3Client
和log
> 在别处声明和初始化。方法返回一个布尔值,但可以抛出异常。The other answers are for AWS SDK v1. Here is a method for AWS SDK v2 (currently 2.3.9).
Note that
getObjectMetadata
anddoesObjectExist
methods are not currently in the v2 SDK! So those are no longer options. We are forced to use eithergetObject
orlistObjects
.listObjects
calls are currently 12.5 times more expensive to make thangetObject
. But AWS also charges for any data downloaded, which raises the price ofgetObject
if the file exists. As long as the file is very unlikely to exist (for example, you have generated a new UUID key randomly and just need to double-check that it isn't taken) then callinggetObject
is significantly cheaper by my calculation.Just to be on the safe side though, I added a
range()
specification to ask AWS to only send a few bytes of the file. As far as I know the SDK will always respect this and not charge you for downloading the whole file. But I haven't verified that so rely on that behavior at your own risk! (Also, I'm not sure what howrange
behaves if the S3 object is 0 bytes long.)Note: this code assumes
s3Client
andlog
are declared and initialized elsewhere. Method returns a boolean, but can throw exceptions.使用对象列表。用于检查 AWS S3 中是否存在指定密钥的 Java 函数。
Using Object isting. Java function to check if specified key exist in AWS S3.
有一种简单的方法可以使用 jetS3t API 的 isObjectInBucket() 方法来完成此操作。
示例代码:
There is an easy way to do it using jetS3t API's isObjectInBucket() method.
Sample code:
我也遇到这个问题
当我使用时,
我得到错误密钥未找到
当我点击并尝试
它工作时,此代码适用于 1.9 jar,否则更新到 1.11 并使用 doesObjectExist 如上所述
I also faced this problem
when I used
I got error key not found
When I hit and try
it worked , this code is working with 1.9 jar otherwise update to 1.11 and use doesObjectExist as said above
使用 jets3t 库。它比 AWS sdk 更简单、更强大。使用此库,您可以调用 s3service.getObjectDetails()。这将仅检查和检索对象的详细信息(而不是对象的内容)。如果对象丢失,它将抛出 404。因此,您可以捕获该异常并在您的应用程序中处理它。
但为了使其发挥作用,您需要拥有该存储桶上的用户的 ListBucket 访问权限。仅 GetObject 访问是行不通的。原因是,如果您没有 ListBucket 访问权限,亚马逊将阻止您检查密钥是否存在。在某些情况下,只要知道密钥是否存在,对于恶意用户来说就足够了。因此,除非他们具有 ListBucket 访问权限,否则他们将无法这样做。
Use the jets3t library. Its a lot more easier and robust than the AWS sdk. Using this library you can call, s3service.getObjectDetails(). This will check and retrieve only the details of the object (not the contents) of the object. It will throw a 404 if the object is missing. So you can catch that exception and deal with it in your app.
But in order for this to work, you will need to have ListBucket access for the user on that bucket. Just GetObject access will not work. The reason being, Amazon will prevent you from checking for the presence of the key if you dont have ListBucket access. Just knowing whether a key is present or not, will also suffice for malicious users in some cases. Hence unless they have ListBucket access they will not be able to do so.
也许这会起作用?
Maybe this will work ?
或者,您可以使用 Minio-Java 客户端库,它是开源的并且与 AWS S3 API 兼容。
您可以使用 Minio-Java StatObject.java 示例对于同样的。
我希望它有帮助。
免责声明:我为 Minio 工作
Alternatively you can use Minio-Java client library, its Open Source and compatible with AWS S3 API.
You can use Minio-Java StatObject.java examples for the same.
I hope it helps.
Disclaimer : I work for Minio