it-swarm.com.de

Auflisten von Dateien in einem bestimmten "Ordner" eines AWS S3-Buckets

Ich muss alle Dateien auflisten, die in einem bestimmten Ordner in meinem S3-Bucket enthalten sind.

Die Ordnerstruktur sieht wie folgt aus

/my-bucket/users/<user-id>/contacts/<contact-id>

Ich habe Dateien, die sich auf Benutzer beziehen, und Dateien, die sich auf den Kontakt eines bestimmten Benutzers beziehen .. __ Ich muss beide auflisten.

Um Dateien aufzulisten, verwende ich diesen Code:

ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName("my-bucket")
                .withPrefix("some-prefix").withDelimiter("/");
ObjectListing objects = transferManager.getAmazonS3Client().listObjects(listObjectsRequest);

Um die Dateien eines bestimmten Benutzers aufzulisten, verwende ich dieses Präfix: 

users/<user-id>/ 

und ich erhalte korrekt alle Dateien im Verzeichnis mit Ausnahme des Unterverzeichnisses contacts, zum Beispiel:

users/<user-id>/file1.txt
users/<user-id>/file2.txt
users/<user-id>/file3.txt

Um stattdessen die Dateien eines bestimmten Benutzerkontakts aufzulisten, verwende ich dieses Präfix: 

users/<user-id>/contacts/<contact-id>/

in diesem Fall erhalte ich aber auch das -Verzeichnis selbst als zurückgegebenes Objekt:

users/<user-id>/contacts/<contact-id>/file1.txt
users/<user-id>/contacts/<contact-id>/file2.txt
users/<user-id>/contacts/<contact-id>/

Warum bekomme ich dieses Verhalten? Was ist der Unterschied zwischen den beiden Anfragen? Ich muss nur Dateien im Verzeichnis auflisten, ausgenommen Unterverzeichnisse.

29
davioooh

Alles in S3 ist ein Objekt. Für Sie kann es sich um Dateien und Ordner handeln. Aber für S3 sind es nur Objekte.

Objekte, die mit dem Trennzeichen (in den meisten Fällen /) enden, werden normalerweise als Ordner wahrgenommen. Dies ist jedoch nicht immer der Fall. Das hängt von der Anwendung ab. Auch in Ihrem Fall interpretieren Sie es als Ordner. S3 ist nicht. Es ist nur ein anderes Objekt.

In Ihrem obigen Fall existiert das Objekt users/<user-id>/contacts/<contact-id>/ in S3 als separates Objekt, das Objekt users/<user-id>/ jedoch nicht. Das ist der Unterschied in deinen Antworten. Warum sie so sind, können wir Ihnen nicht sagen, aber jemand hat das Objekt in einem Fall gemacht und im anderen Fall nicht. Sie finden es nicht in der AWS Management Console, da die Konsole es als Ordner interpretiert und vor Ihnen verbirgt.

Da S3 diese Dinge nur als Objekte sieht, werden bestimmte Dinge für Sie nicht "ausgeschlossen". Es ist Sache des Kunden, mit den Objekten so umzugehen, wie sie behandelt werden sollen.

Ihre Lösung

Da Sie die Ordnerobjekte nicht möchten, können Sie sie selbst ausschließen, indem Sie das letzte Zeichen auf / überprüfen. Ist dies der Fall, ignorieren Sie das Objekt in der Antwort.

18
Matt Houser

Während alle sagen, dass es keine Verzeichnisse und Dateien in s3 gibt, sondern nur Objekte (und Buckets), was absolut wahr ist, würde ich empfehlen, CommonPrefixes zu nutzen, die in this answer ..__ beschrieben sind Sie können folgendermaßen vorgehen, um eine Liste von "Ordnern" (commonPrefixes) und "Dateien" (objectSummaries) zu erhalten:

ListObjectsV2Request req = new ListObjectsV2Request().withBucketName(bucket.getName()).withPrefix(prefix).withDelimiter(DELIMITER);
ListObjectsV2Result listing = s3Client.listObjectsV2(req);
for (String commonPrefix : listing.getCommonPrefixes()) {
        System.out.println(commonPrefix);
}
for (S3ObjectSummary summary: listing.getObjectSummaries()) {
    System.out.println(summary.getKey());
}

In Ihrem Fall sollte objectSummaries (Dateien) (bei korrektem Präfix) Folgendes zurückgeben: 
Benutzer/Benutzer-ID/Kontakte/Kontakt-ID/Datei1.txt
users/benutzer-id/kontakte/kontakt-id/datei2.txt

für commonPrefixes:
Benutzer/Benutzer-ID/Kontakte/Kontakt-ID/

18
Vic K

Wie andere schon gesagt haben, ist alles in S3 ein Objekt. Für Sie kann es sich um Dateien und Ordner handeln. Aber für S3 sind es nur Objekte.

Wenn Sie keine Objekte benötigen, die mit einem "/" enden, können Sie sie sicher löschen, z. über REST api oder AWS Java SDK (ich gehe davon aus, dass Sie Schreibzugriff haben). Sie werden keine "verschachtelten Dateien" verlieren (es gibt keine Dateien, damit Sie keine Objekte verlieren, deren Namen den zu löschenden Schlüssel enthalten).

AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard().withCredentials(new ProfileCredentialsProvider()).withRegion("region").build();
amazonS3.deleteObject(new DeleteObjectRequest("my-bucket", "users/<user-id>/contacts/<contact-id>/"));

Bitte beachten Sie, dass ich ProfileCredentialsProvider verwende, damit meine Anfragen nicht anonym sind. Andernfalls können Sie ein Objekt nicht löschen. Ich habe meinen AWS-Schlüssel in der Datei ~/.aws/credentials gespeichert.

0
MrKiller21

sie können den Typ überprüfen. s3 hat ein spezielles application/x-verzeichnis

bucket.objects({:delimiter=>"/", :prefix=>"f1/"}).each { |obj| p obj.object.content_type }
0
Yaroslav Malyk

S3 hat keine Verzeichnisse. Sie können Dateien zwar in einem Pseudo-Verzeichnis auflisten, wie Sie es gezeigt haben, es gibt jedoch kein Verzeichnis "Datei" an sich.
.__ Sie können versehentlich eine Datendatei mit dem Namen users/<user-id>/contacts/<contact-id>/ erstellt haben.

0
Magnus