Ich möchte mit Java überprüfen, ob ein Schlüssel in einem bestimmten Bucket vorhanden ist. Ich habe mir die API angesehen, aber es gibt keine nützlichen Methoden. Ich habe versucht zu verwenden, getObject
aber es warf eine Ausnahme.
java
amazon-web-services
amazon-s3
aws-sdk
in seinen Schritten
quelle
quelle
Antworten:
Verwenden Sie die jets3t-Bibliothek. Es ist viel einfacher und robuster als das AWS SDK. Mit dieser Bibliothek können Sie s3service.getObjectDetails () aufrufen. Dadurch werden nur die Details des Objekts (nicht der Inhalt) des Objekts überprüft und abgerufen. Es wird eine 404 geworfen, wenn das Objekt fehlt. So können Sie diese Ausnahme abfangen und in Ihrer App behandeln.
Damit dies funktioniert, benötigen Sie jedoch ListBucket-Zugriff für den Benutzer in diesem Bucket. Nur GetObject-Zugriff funktioniert nicht. Der Grund dafür ist, dass Amazon Sie daran hindert, das Vorhandensein des Schlüssels zu überprüfen, wenn Sie keinen ListBucket-Zugriff haben. Nur zu wissen, ob ein Schlüssel vorhanden ist oder nicht, reicht in einigen Fällen auch für böswillige Benutzer aus. Daher können sie dies nicht tun, es sei denn, sie haben ListBucket-Zugriff.
quelle
Es gibt jetzt eine doesObjectExist- Methode in der offiziellen Java-API.
Genießen!
quelle
doesObjectExist
aus dem 2.x SDK entfernt wurde (derzeit v2.3.9).Aktualisieren:
Es scheint, dass es eine neue API gibt, um genau das zu überprüfen. Eine weitere Antwort finden Sie auf dieser Seite: https://stackoverflow.com/a/36653034/435605
Ursprünglicher Beitrag:
Verwenden
errorCode.equals("NoSuchKey")
Hinweis zur Ausnahme: Ich weiß, dass Ausnahmen nicht für die Flusskontrolle verwendet werden sollten. Das Problem ist, dass Amazon keine API zur Überprüfung dieses Ablaufs bereitgestellt hat - nur eine Dokumentation über die Ausnahme.
quelle
errorMessage
auf "Nicht gefunden" gesetzt ist, aber daserrorCode
ist null.NoSuchKey
. Eine endgültige Liste der S3-Fehlercodes finden Sie in der Dokumentation: docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.htmlVerwenden Sie für das AWS SDK die Methode getObjectMetadata. Die Methode löst eine AmazonServiceException aus, wenn der Schlüssel nicht vorhanden ist.
quelle
In Amazon Java SDK 1.10+ können Sie
getStatusCode()
den Statuscode der HTTP-Antwort abrufen, der 404 lautet, wenn das Objekt nicht vorhanden ist.getObjectMetadata()
verbraucht weniger Ressourcen und die Antwort muss nicht wie geschlossen werdengetObject()
.In früheren Versionen können Sie
getErrorCode()
die entsprechende Zeichenfolge verwenden und nach ihr suchen (abhängig von der Version).quelle
Verwenden Sie das ListObjectsRequest-Einstellungspräfix als Schlüssel.
.NET-Code:
quelle
Für PHP (ich weiß, dass die Frage Java ist, aber Google hat mich hierher gebracht) können Sie Stream-Wrapper und file_exists verwenden
quelle
Dieser Java-Code prüft, ob der Schlüssel (die Datei) im s3-Bucket vorhanden ist.
quelle
Brechen Sie Ihren Weg in Eimer und Objekt. Testen des Buckets mit der Methode
doesBucketExist
, Testen des Objekts mit der Größe der Auflistung (0, falls nicht vorhanden). Dieser Code reicht also aus:quelle
Verwenden von Objectisting. Java-Funktion zum Überprüfen, ob der angegebene Schlüssel in AWS S3 vorhanden ist.
quelle
Es gibt eine einfache Möglichkeit, dies mit der isObjectInBucket () -Methode der jetS3t-API zu tun.
Beispielcode:
quelle
Die anderen Antworten beziehen sich auf AWS SDK v1. Hier ist eine Methode für AWS SDK v2 (derzeit 2.3.9).
Beachten Sie, dass
getObjectMetadata
unddoesObjectExist
Methoden derzeit nicht im v2 SDK enthalten sind! Das sind also keine Optionen mehr. Wir sind gezwungen, entwedergetObject
oder zu verwendenlistObjects
.listObjects
Anrufe sind derzeit 12,5-mal teurer alsgetObject
. AWS berechnet jedoch auch Gebühren für heruntergeladene Daten, was den Preis erhöht,getObject
wenn die Datei vorhanden ist . Solange es sehr unwahrscheinlich ist, dass die Datei existiert (Sie haben beispielsweise zufällig einen neuen UUID-Schlüssel generiert und müssen nur überprüfen, ob er nicht verwendet wird),getObject
ist das Aufrufen nach meiner Berechnung erheblich billiger.Um auf der sicheren Seite zu sein, habe ich eine
range()
Spezifikation hinzugefügt , um AWS zu bitten, nur einige Bytes der Datei zu senden. Soweit ich weiß, wird das SDK dies immer respektieren und Ihnen keine Gebühren für das Herunterladen der gesamten Datei berechnen. Aber ich habe das nicht überprüft, also verlasse dich auf dieses Verhalten auf eigenes Risiko! (Ich bin mir auch nicht sicher, wie ich michrange
verhalte, wenn das S3-Objekt 0 Byte lang ist.)Hinweis: Dieser Code geht davon aus
s3Client
undlog
wird an anderer Stelle deklariert und initialisiert. Die Methode gibt einen Booleschen Wert zurück, kann jedoch Ausnahmen auslösen.quelle
s3Client.headObject()
in V2 eine Möglichkeit , dies zu tun: stackoverflow.com/a/56949742/9814131 , und Sie überprüfen denS3Exception
Statuscode 404 des S, um zu überprüfen, ob das Objekt gemäß dem Github-Problem github.com/aws/aws-sdk- vorhanden ist. Java-v2 / Issues / 297 . Aber ich denke, Ihre sind progressiver, da sie nur einen geringen Overhead von 0-3 Bytes haben.Der richtige Weg, dies in SDK V2 zu tun, ohne das Objekt tatsächlich abzurufen , ist die Verwendung von S3Client.headObject . Offiziell unterstützt von AWS Change Log .
quelle
Alternativ können Sie die Minio-Java- Clientbibliothek Open Source verwenden, die mit der AWS S3-API kompatibel ist.
Sie können dafür Minio-Java StatObject.java- Beispiele verwenden.
Ich hoffe, es hilft.
Haftungsausschluss: Ich arbeite für Minio
quelle
Wie bereits erwähnt, können Sie für das AWS S3 Java SDK 2.10+ das HeadObjectRequest- Objekt verwenden, um zu überprüfen, ob sich eine Datei in Ihrem S3-Bucket befindet. Dies verhält sich wie eine GET-Anforderung, ohne die Datei tatsächlich abzurufen.
Beispielcode, da andere oben keinen Code hinzugefügt haben:
quelle
headObjectResponse
.throws Exception
wird auch nicht benötigt.Ich war auch mit diesem Problem konfrontiert, als ich es benutzte
Ich habe den Fehlerschlüssel nicht gefunden
Wenn ich treffe und es versuche
es hat funktioniert, dieser Code funktioniert mit 1.9 jar, andernfalls aktualisieren Sie auf 1.11 und verwenden Sie doesObjectExist wie oben beschrieben
quelle