Liste des fichiers dans un «dossier» spécifique d’un compartiment AWS S3

Je dois répertorier tous les fichiers contenus dans un dossier spécifique contenu dans mon compartiment S3.

La structure de dossier est la suivante

/my-bucket/users//contacts/ 

J’ai des fichiers liés aux utilisateurs et des fichiers liés au contact d’un utilisateur donné. J’ai besoin d’énumérer les deux.

Pour lister les fichiers, j’utilise ce code:

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

Pour répertorier les fichiers de certains utilisateurs, j’utilise ce préfixe:

users//

et je récupère correctement tous les fichiers du répertoire, à l’exception du sous-répertoire contacts , par exemple:

 users//file1.txt users//file2.txt users//file3.txt 

Pour lister les fichiers d’un contact utilisateur spécifique, j’utilise ce préfixe:

users//contacts//

mais dans ce cas, je reçois aussi le répertoire lui-même en tant qu’object retourné:

 users//contacts//file1.txt users//contacts//file2.txt users//contacts// 

Pourquoi ai-je ce comportement? Quelle est la différence entre les deux demandes d’inscription? Je n’ai besoin de lister que les fichiers du répertoire, à l’exclusion des sous-répertoires.

    Tout en S3 est un object. Pour vous, il peut s’agir de fichiers et de dossiers. Mais pour S3, ce ne sont que des objects.

    Les objects qui se terminent par le délimiteur ( / dans la plupart des cas) sont généralement perçus comme un dossier, mais ce n’est pas toujours le cas. Cela dépend de l’application. Encore une fois, dans votre cas, vous l’interprétez comme un dossier. S3 n’est pas. C’est juste un autre object.

    Dans votre cas ci-dessus, l’object users//contacts// existe dans S3 en tant qu’object distinct, mais l’object users// ne le fait pas. C’est la différence dans vos réponses. Pourquoi ils sont comme ça, on ne peut pas vous le dire, mais quelqu’un a fait l’object dans un cas, et pas dans l’autre. Vous ne le voyez pas dans AWS Management Console car la console l’interprète comme un dossier et vous le cache.

    Puisque S3 ne voit que ces choses comme des objects, il ne “exclura” pas certaines choses pour vous. Il appartient au client de traiter les objects comme ils doivent être traités.

    Votre solution

    Puisque vous ne voulez pas les objects de dossier, vous pouvez les exclure vous-même en vérifiant le dernier caractère d’un / . Si c’est le cas, ignorez l’object de la réponse.

    Alors que tout le monde dit qu’il n’y a pas de répertoires et de fichiers dans s3, mais seulement des objects (et des compartiments), ce qui est absolument vrai, je suggère de tirer parti des CommonPrefix, décrits dans cette réponse. Donc, vous pouvez faire ce qui suit pour obtenir la liste des “dossiers” (commonPrefixes) et des “fichiers” (objectSummaries):

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

    Dans votre cas, pour objectSummaries (fichiers), il devrait renvoyer (en cas de préfixe correct):
    utilisateurs / id-utilisateur / contacts / id-contact / fichier1.txt
    utilisateurs / id-utilisateur / contacts / id-contact / fichier2.txt

    pour commonPrefixes:
    users / id-utilisateur / contacts / id-de-contact /

    S3 ne possède pas de répertoires. Vous pouvez répertorier les fichiers de manière pseudo-répertoire, comme vous l’avez démontré, mais il n’y a pas de répertoire “fichier” en tant que tel.
    Vous avez peut-être créé par inadvertance un fichier de données appelé users//contacts// .

    vous pouvez vérifier le type. s3 a une application spéciale / x-directory

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