如何检查指定的密钥是否存在于使用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桶和对象。 使用方法doesBucketExist
testing存储桶,使用列表大小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工作