如何检查指定的密钥是否存在于使用Java的给定S3存储桶中

我想检查一个关键是否存在于一个给定的桶使用Java。 我看了一下API,但没有任何有用的方法。 我试图使用getObject但它抛出了一个exception。

使用jets3t库。 它比AWS sdk更容易和更强大。 使用这个库你可以调用s3service.getObjectDetails()。 这将检查和检索对象的对象(而不是内容)的细节。 如果对象丢失,它将会抛出一个404。 所以你可以捕捉到这个exception,并在你的应用程序中处理它。

但为了这个工作,你需要有ListBucket访问该桶上的用户。 只是GetObject访问不起作用。 原因是,如果您没有ListBucket访问,Amazon将阻止您检查密钥的存在。 只要知道密钥是否存在,在某些情况下也足以满足恶意用户的需求。 因此,除非他们有ListBucket访问,他们将无法这样做。

现在在官方Java API中有一个doesObjectExist方法。

请享用!

使用errorCode.equals("NoSuchKey")

 try { AmazonS3 s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider()); String bucketName = getBucketName(); s3.createBucket(bucketName); S3Object object = s3.getObject(bucketName, getKey()); } catch (AmazonServiceException e) { String errorCode = e.getErrorCode(); if (!errorCode.equals("NoSuchKey")) { throw e; } Logger.getLogger(getClass()).debug("No such key!!!", e); } 

关于exception的注意事项:我知道exception不应该用于stream量控制。 问题是,亚马逊没有提供任何API来检查这个stream程 – 只是关于例外的文档。

使用AWS SDK使用getObjectMetadata方法。 如果密钥不存在,该方法将抛出AmazonServiceException。

 private AmazonS3 s3; ... public boolean exists(String path, String name) { try { s3.getObjectMetadata(bucket, getS3Path(path) + name); } catch(AmazonServiceException e) { return false; } return true; } 

在Amazon Java SDK 1.10+中,可以使用getStatusCode()获取HTTP响应的状态码,如果对象不存在,则返回404。

 import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.AmazonS3Exception; import org.apache.http.HttpStatus; try { AmazonS3 s3 = new AmazonS3Client(); S3Object object = s3.getObjectMetadata("my-bucket", "my-client"); } catch (AmazonS3Exception e) { if (e.getStatusCode() == HttpStatus.SC_NOT_FOUND) { // bucket/key does not exist } else { throw e; } } 

getObjectMetadata()消耗更less的资源,并且不需要像getObject()那样closures响应。


在以前的版本中,可以使用getErrorCode()并检查相应的string(取决于版本)。

使用ListObjectsRequest设置前缀作为您的键。

.NET代码:

  public bool Exists(string key) { using (Amazon.S3.AmazonS3Client client = (Amazon.S3.AmazonS3Client)Amazon.AWSClientFactory.CreateAmazonS3Client(m_accessKey, m_accessSecret)) { ListObjectsRequest request = new ListObjectsRequest(); request.BucketName = m_bucketName; request.Prefix = key; using (ListObjectsResponse response = client.ListObjects(request)) { foreach (S3Object o in response.S3Objects) { if( o.Key == key ) return true; } return false; } } }. 

这个java代码检查密钥(文件)是否存在于s3桶中。

 public static boolean isExistS3(String accessKey, String secretKey, String bucketName, String file) { // Amazon-s3 credentials AWSCredentials myCredentials = new BasicAWSCredentials(accessKey, secretKey); AmazonS3Client s3Client = new AmazonS3Client(myCredentials); ObjectListing objects = s3Client.listObjects(new ListObjectsRequest().withBucketName(bucketName).withPrefix(file)); for (S3ObjectSummary objectSummary: objects.getObjectSummaries()) { if (objectSummary.getKey().equals(file)) { return true; } } return false; } 

对于PHP(我知道问题是Java,但Google把我带到这里),你可以使用stream包装和file_exists

 $bucket = "MyBucket"; $key = "MyKey"; $s3 = Aws\S3\S3Client->factory([...]); $s3->registerStreamWrapper(); $keyExists = file_exists("s3://$bucket/$key"); 

使用对象isting。 Java函数来检查AWS S3中是否存在指定的密钥。

 boolean isExist(String key) { ObjectListing objects = amazonS3.listObjects(new ListObjectsRequest().withBucketName(bucketName).withPrefix(key)); for (S3ObjectSummary objectSummary : objects.getObjectSummaries()) { if (objectSummary.getKey().equals(key)) { return true; } } return false; } 

打破你的path桶和对象。 使用方法doesBucketExisttesting存储桶,使用列表大小testing对象(如果不存在, doesBucketExist 0)。 所以这段代码会做:

 String bucket = ...; String objectInBucket = ...; AmazonS3 s3 = new AmazonS3Client(...); return s3.doesBucketExist(bucket) && !s3.listObjects(bucket, objectInBucket).getObjectSummaries().isEmpty(); 

使用jetS3t API的isObjectInBucket()方法有一个简单的方法。

示例代码:

 ProviderCredentials awsCredentials = new AWSCredentials( awsaccessKey, awsSecretAcessKey); // REST implementation of S3Service RestS3Service restService = new RestS3Service(awsCredentials); // check whether file exists in bucket if (restService.isObjectInBucket(bucket, objectKey)) { //your logic } 

或者,您可以使用Minio-Java客户端库,其开放源代码并与AWS S3 API兼容。

您可以使用Minio -Java StatObject.java示例。

导入io.minio.MinioClient;
 import io.minio.errors.MinioException;

 import java.io.InputStream;
 import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
 import java.security.InvalidKeyException;

 import org.xmlpull.v1.XmlPullParserException;


公共类GetObject {
   public static void main(String [] args)
    抛出NoSuchAlgorithmException,IOException,InvalidKeyException,XmlPullParserException,MinioException {
     //注意:您的ACCESSKEYID,YOUR-SECRETACCESSKEY和my-bucketname是
     //虚拟值,请将其replace为原始值。
     //设置s3端点,区域自动计算
     MinioClient s3Client = new MinioClient(“https://s3.amazonaws.com”,“YOUR-ACCESSKEYID”,“YOUR-SECRETACCESSKEY”);
     InputStream stream = s3Client.getObject(“my-bucketname”,“my-objectname”);

     byte [] buf =新字节[16384];
     int bytesRead;
     while((bytesRead = stream.read(buf,0,buf.length))> = 0){
       System.out.println(new String(buf,0,bytesRead));
     }

     stream.close();
   }
 }

我希望它有帮助。

免责声明:我为Minio工作