Je voudrais vérifier si une clé existe dans un seau donné en utilisant Java. J'ai regardé l'API mais aucune méthode n'est utile. J'ai essayé d'utiliser getObject
mais cela a jeté une exception.
java
amazon-web-services
amazon-s3
aws-sdk
dans ses pas
la source
la source
Réponses:
Utilisez la bibliothèque jets3t. C'est beaucoup plus facile et robuste que le sdk AWS. En utilisant cette bibliothèque, vous pouvez appeler s3service.getObjectDetails (). Cela vérifiera et ne récupérera que les détails de l'objet (pas le contenu) de l'objet. Il lancera un 404 si l'objet est manquant. Vous pouvez donc intercepter cette exception et la gérer dans votre application.
Mais pour que cela fonctionne, vous devez disposer d'un accès ListBucket pour l'utilisateur sur ce compartiment. L'accès à GetObject ne fonctionnera pas. La raison en est qu'Amazon vous empêchera de vérifier la présence de la clé si vous n'avez pas accès à ListBucket. Le simple fait de savoir si une clé est présente ou non suffira également aux utilisateurs malveillants dans certains cas. Par conséquent, à moins d'avoir accès à ListBucket, ils ne pourront pas le faire.
la source
Il existe maintenant une méthode doesObjectExist dans l'API Java officielle.
Prendre plaisir!
la source
doesObjectExist
du SDK 2.x (actuellement v2.3.9).Mise à jour:
Il semble qu'il existe une nouvelle API pour vérifier cela. Voir une autre réponse dans cette page: https://stackoverflow.com/a/36653034/435605
Message d'origine:
Utilisation
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); }
Remarque sur l'exception: je sais que les exceptions ne doivent pas être utilisées pour le contrôle de flux. Le problème est qu'Amazon n'a fourni aucune API pour vérifier ce flux - juste de la documentation sur l'exception.
la source
errorMessage
est défini sur "Not Found", mais leerrorCode
est nul.NoSuchKey
. Pour une liste définitive des codes d'erreur S3, consultez la documentation: docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.htmlÀ l'aide du kit SDK AWS, utilisez la méthode getObjectMetadata. La méthode lèvera une AmazonServiceException si la clé n'existe pas.
private AmazonS3 s3; ... public boolean exists(String path, String name) { try { s3.getObjectMetadata(bucket, getS3Path(path) + name); } catch(AmazonServiceException e) { return false; } return true; }
la source
Dans Amazon Java SDK 1.10+, vous pouvez utiliser
getStatusCode()
pour obtenir le code d'état de la réponse HTTP, qui sera 404 si l'objet n'existe pas.import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.AmazonS3Exception; import org.apache.http.HttpStatus; try { AmazonS3 s3 = new AmazonS3Client(); ObjectMetadata 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()
consomme moins de ressources et la réponse n'a pas besoin d'être fermée commegetObject()
.Dans les versions précédentes, vous pouvez utiliser
getErrorCode()
et vérifier la chaîne appropriée (dépend de la version).la source
Utilisez ListObjectsRequest setting Prefix comme clé.
Code .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; } } }.
la source
Pour PHP (je sais que la question est Java, mais Google m'a amené ici), vous pouvez utiliser des wrappers de flux et file_exists
$bucket = "MyBucket"; $key = "MyKey"; $s3 = Aws\S3\S3Client->factory([...]); $s3->registerStreamWrapper(); $keyExists = file_exists("s3://$bucket/$key");
la source
Ce code java vérifie si la clé (fichier) existe dans le compartiment 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; }
la source
Divisez votre chemin en seau et objet. Test du bucket à l'aide de la méthode
doesBucketExist
, Test de l'objet à l'aide de la taille de la liste (0 en cas d'existence) Donc, ce code fera:String bucket = ...; String objectInBucket = ...; AmazonS3 s3 = new AmazonS3Client(...); return s3.doesBucketExist(bucket) && !s3.listObjects(bucket, objectInBucket).getObjectSummaries().isEmpty();
la source
Utiliser Object isting. Fonction Java pour vérifier si la clé spécifiée existe dans 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; }
la source
Il existe un moyen simple de le faire en utilisant la méthode isObjectInBucket () de l'API jetS3t.
Exemple de code:
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 }
la source
Les autres réponses concernent AWS SDK v1. Voici une méthode pour AWS SDK v2 (actuellement 2.3.9).
Notez que les méthodes
getObjectMetadata
etdoesObjectExist
ne sont pas actuellement dans le SDK v2! Ce ne sont donc plus des options. Nous sommes obligés d'utiliser soitgetObject
oulistObjects
.listObjects
les appels sont actuellement 12,5 fois plus chers à faire quegetObject
. Mais AWS facture également toutes les données téléchargées, ce qui augmente le prix degetObject
l'existence du fichier . Tant qu'il est très peu probable que le fichier existe (par exemple, vous avez généré une nouvelle clé UUID de manière aléatoire et devez simplement vérifier qu'elle n'est pas prise), puis appelezgetObject
est nettement moins cher selon mon calcul.Par souci de sécurité, j'ai ajouté une
range()
spécification demandant à AWS de n'envoyer que quelques octets du fichier. Autant que je sache, le SDK respectera toujours cela et ne vous facturera pas pour le téléchargement du fichier entier. Mais je n'ai pas vérifié cela, alors comptez sur ce comportement à vos risques et périls! (De plus, je ne sais pas commentrange
se comporte si l'objet S3 a une longueur de 0 octet.)private boolean sanityCheckNewS3Key(String bucket, String key) { ResponseInputStream<GetObjectResponse> resp = null; try { resp = s3client.getObject(GetObjectRequest.builder() .bucket(bucket) .key(key) .range("bytes=0-3") .build()); } catch (NoSuchKeyException e) { return false; } catch (AwsServiceException se) { throw se; } finally { if (resp != null) { try { resp.close(); } catch (IOException e) { log.warn("Exception while attempting to close S3 input stream", e); } } } return true; } }
Remarque: ce code suppose
s3Client
etlog
est déclaré et initialisé ailleurs. La méthode renvoie un booléen, mais peut lever des exceptions.la source
s3Client.headObject()
dans V2 pour faire ceci: stackoverflow.com/a/56949742/9814131 , et vous vérifierez leS3Exception
code de statut 404 pour vérifier si l'objet existe selon le problème github github.com/aws/aws-sdk- java-v2 / issues / 297 . Mais je suppose que le vôtre est plus progressif car il a aussi très peu de frais généraux que 0-3 octets.La bonne façon de le faire dans SDK V2, sans la surcharge liée à l'obtention de l'objet, est d'utiliser S3Client.headObject . Officiellement soutenu par AWS Change Log .
la source
J'ai également rencontré ce problème lorsque j'utilisais
String BaseFolder = "3patti_Logs"; S3Object object = s3client.getObject(bucketName, BaseFolder);
J'ai la clé d'erreur introuvable
Quand je frappe et essaie
String BaseFolder = "3patti_Logs"; S3Object object = s3client.getObject(bucketName, BaseFolder+"/");
cela a fonctionné, ce code fonctionne avec 1.9 jar sinon mettez à jour à 1.11 et utilisez doObjectExist comme indiqué ci-dessus
la source
Comme d'autres l'ont mentionné, pour AWS S3 Java SDK 2.10+, vous pouvez utiliser l' objet HeadObjectRequest pour vérifier s'il existe un fichier dans votre compartiment S3. Cela agira comme une requête GET sans obtenir le fichier.
Exemple de code puisque les autres n'ont en fait ajouté aucun code ci-dessus:
public boolean existsOnS3 () throws Exception { try { S3Client s3Client = S3Client.builder ().credentialsProvider (...).build (); HeadObjectRequest headObjectRequest = HeadObjectRequest.builder ().bucket ("my-bucket").key ("key/to/file/house.pdf").build (); HeadObjectResponse headObjectResponse = s3Client.headObject (headObjectRequest); return headObjectResponse.sdkHttpResponse ().isSuccessful (); } catch (NoSuchKeyException e) { //Log exception for debugging return false; } }
la source
headObjectResponse
.throws Exception
n'est pas nécessaire non plus.Vous pouvez également utiliser la bibliothèque cliente Minio-Java , son Open Source et compatible avec l'API AWS S3.
Vous pouvez utiliser des exemples Minio-Java StatObject.java pour le même.
J'espère que cela aide.
Clause de non-responsabilité: je travaille pour Minio
la source